blob: 59b24e54510bbbfc0894b381c90574847bf359a1 [file] [log] [blame]
[email protected]e34400c32012-01-24 02:49:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// 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
[email protected]51fdc7c2012-04-10 19:19:487#include <vector>
8
[email protected]6ecf2b92011-12-15 01:14:529#include "base/bind.h"
10#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:5911#include "base/callback.h"
[email protected]3b63f8f42011-03-28 01:54:1512#include "base/memory/ref_counted.h"
13#include "base/memory/scoped_vector.h"
[email protected]6ea7b152011-12-21 21:21:1314#include "base/memory/weak_ptr.h"
[email protected]f6d1d6eb2009-06-24 20:16:0915#include "base/message_loop.h"
[email protected]034df0f32013-01-07 23:17:4816#include "base/run_loop.h"
[email protected]1870d5cf2011-05-12 01:55:4017#include "base/stringprintf.h"
[email protected]e83326f2010-07-31 17:29:2518#include "base/string_number_conversions.h"
[email protected]f214f8792011-01-01 02:17:0819#include "base/threading/platform_thread.h"
[email protected]f3a1c642011-07-12 19:15:0320#include "base/values.h"
[email protected]034df0f32013-01-07 23:17:4821#include "net/base/load_timing_info.h"
[email protected]b258e0792013-01-12 07:11:5922#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0623#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5324#include "net/base/net_log.h"
25#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3126#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0927#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3528#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0929#include "net/socket/client_socket_factory.h"
30#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0031#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1732#include "net/socket/socket_test_util.h"
[email protected]3268023f2011-05-05 00:08:1033#include "net/socket/stream_socket.h"
[email protected]51fdc7c2012-04-10 19:19:4834#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0935#include "testing/gtest/include/gtest/gtest.h"
36
[email protected]51fdc7c2012-04-10 19:19:4837using ::testing::Invoke;
38using ::testing::Return;
39
[email protected]f6d1d6eb2009-06-24 20:16:0940namespace net {
41
42namespace {
43
[email protected]211d21722009-07-22 15:48:5344const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2045const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5246const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0147
[email protected]034df0f32013-01-07 23:17:4848// Make sure |handle| sets load times correctly when it has been assigned a
49// reused socket.
50void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
51 LoadTimingInfo load_timing_info;
52 // Only pass true in as |is_reused|, as in general, HttpStream types should
53 // have stricter concepts of reuse than socket pools.
54 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
55
56 EXPECT_EQ(true, load_timing_info.socket_reused);
57 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
58
[email protected]b258e0792013-01-12 07:11:5959 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
60 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4861}
62
63// Make sure |handle| sets load times correctly when it has been assigned a
64// fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
65// of a connection where |is_reused| is false may consider the connection
66// reused.
67void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
68 EXPECT_FALSE(handle.is_reused());
69
70 LoadTimingInfo load_timing_info;
71 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
72
73 EXPECT_FALSE(load_timing_info.socket_reused);
74 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
75
[email protected]b258e0792013-01-12 07:11:5976 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
77 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
78 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4879
80 TestLoadTimingInfoConnectedReused(handle);
81}
82
83// Make sure |handle| sets load times correctly, in the case that it does not
84// currently have a socket.
85void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
86 // Should only be set to true once a socket is assigned, if at all.
87 EXPECT_FALSE(handle.is_reused());
88
89 LoadTimingInfo load_timing_info;
90 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
91
92 EXPECT_FALSE(load_timing_info.socket_reused);
93 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
94
[email protected]b258e0792013-01-12 07:11:5995 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
96 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
[email protected]034df0f32013-01-07 23:17:4897}
98
[email protected]df4b4ef2010-07-12 18:25:2199class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:20100 public:
[email protected]51fdc7c2012-04-10 19:19:48101 TestSocketParams() : ignore_limits_(false) {}
102
103 void set_ignore_limits(bool ignore_limits) {
104 ignore_limits_ = ignore_limits;
105 }
106 bool ignore_limits() { return ignore_limits_; }
107
[email protected]df4b4ef2010-07-12 18:25:21108 private:
109 friend class base::RefCounted<TestSocketParams>;
110 ~TestSocketParams() {}
[email protected]51fdc7c2012-04-10 19:19:48111
112 bool ignore_limits_;
[email protected]df4b4ef2010-07-12 18:25:21113};
[email protected]7fc5b09a2010-02-27 00:07:38114typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:49115
[email protected]3268023f2011-05-05 00:08:10116class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:09117 public:
[email protected]034df0f32013-01-07 23:17:48118 explicit MockClientSocket(net::NetLog* net_log)
119 : connected_(false),
120 net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)),
[email protected]e86df8dc2013-03-30 13:18:28121 was_used_to_convey_data_(false) {
[email protected]034df0f32013-01-07 23:17:48122 }
[email protected]f6d1d6eb2009-06-24 20:16:09123
[email protected]3f55aa12011-12-07 02:03:33124 // Socket implementation.
[email protected]ab838892009-06-30 18:49:05125 virtual int Read(
[email protected]83039bb2011-12-09 18:43:55126 IOBuffer* /* buf */, int len,
127 const CompletionCallback& /* callback */) OVERRIDE {
[email protected]e86df8dc2013-03-30 13:18:28128 return ERR_UNEXPECTED;
[email protected]3f55aa12011-12-07 02:03:33129 }
[email protected]ab838892009-06-30 18:49:05130
131 virtual int Write(
[email protected]83039bb2011-12-09 18:43:55132 IOBuffer* /* buf */, int len,
133 const CompletionCallback& /* callback */) OVERRIDE {
[email protected]0f873e82010-09-02 16:09:01134 was_used_to_convey_data_ = true;
135 return len;
[email protected]ab838892009-06-30 18:49:05136 }
[email protected]46fadfd2013-02-06 09:40:16137 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE { return true; }
138 virtual bool SetSendBufferSize(int32 size) OVERRIDE { return true; }
[email protected]ab838892009-06-30 18:49:05139
[email protected]dbf036f2011-12-06 23:33:24140 // StreamSocket implementation.
[email protected]83039bb2011-12-09 18:43:55141 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
[email protected]dbf036f2011-12-06 23:33:24142 connected_ = true;
143 return OK;
144 }
[email protected]f6d1d6eb2009-06-24 20:16:09145
[email protected]46fadfd2013-02-06 09:40:16146 virtual void Disconnect() OVERRIDE { connected_ = false; }
147 virtual bool IsConnected() const OVERRIDE { return connected_; }
148 virtual bool IsConnectedAndIdle() const OVERRIDE { return connected_; }
[email protected]0b7648c2009-07-06 20:14:01149
[email protected]46fadfd2013-02-06 09:40:16150 virtual int GetPeerAddress(IPEndPoint* /* address */) const OVERRIDE {
[email protected]9f864b32010-01-20 15:01:16151 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:09152 }
[email protected]f6d1d6eb2009-06-24 20:16:09153
[email protected]46fadfd2013-02-06 09:40:16154 virtual int GetLocalAddress(IPEndPoint* /* address */) const OVERRIDE {
[email protected]e7f74da2011-04-19 23:49:35155 return ERR_UNEXPECTED;
156 }
157
[email protected]46fadfd2013-02-06 09:40:16158 virtual const BoundNetLog& NetLog() const OVERRIDE {
[email protected]a2006ece2010-04-23 16:44:02159 return net_log_;
160 }
161
[email protected]46fadfd2013-02-06 09:40:16162 virtual void SetSubresourceSpeculation() OVERRIDE {}
163 virtual void SetOmniboxSpeculation() OVERRIDE {}
164 virtual bool WasEverUsed() const OVERRIDE {
[email protected]e86df8dc2013-03-30 13:18:28165 return was_used_to_convey_data_;
[email protected]5e6efa52011-06-27 17:26:41166 }
[email protected]46fadfd2013-02-06 09:40:16167 virtual bool UsingTCPFastOpen() const OVERRIDE { return false; }
[email protected]46fadfd2013-02-06 09:40:16168 virtual bool WasNpnNegotiated() const OVERRIDE {
[email protected]2d88e7d2012-07-19 17:55:17169 return false;
170 }
[email protected]46fadfd2013-02-06 09:40:16171 virtual NextProto GetNegotiatedProtocol() const OVERRIDE {
[email protected]33661e482012-04-03 16:16:26172 return kProtoUnknown;
173 }
[email protected]46fadfd2013-02-06 09:40:16174 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
[email protected]2d88e7d2012-07-19 17:55:17175 return false;
176 }
[email protected]9b5614a2010-08-25 20:29:45177
[email protected]f6d1d6eb2009-06-24 20:16:09178 private:
179 bool connected_;
[email protected]a2006ece2010-04-23 16:44:02180 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01181 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:09182
[email protected]ab838892009-06-30 18:49:05183 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09184};
185
[email protected]5fc08e32009-07-15 17:09:57186class TestConnectJob;
187
[email protected]f6d1d6eb2009-06-24 20:16:09188class MockClientSocketFactory : public ClientSocketFactory {
189 public:
[email protected]ab838892009-06-30 18:49:05190 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09191
[email protected]98b0e582011-06-22 14:31:41192 virtual DatagramClientSocket* CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04193 DatagramSocket::BindType bind_type,
194 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41195 NetLog* net_log,
[email protected]46fadfd2013-02-06 09:40:16196 const NetLog::Source& source) OVERRIDE {
[email protected]98b0e582011-06-22 14:31:41197 NOTREACHED();
198 return NULL;
199 }
200
[email protected]3268023f2011-05-05 00:08:10201 virtual StreamSocket* CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07202 const AddressList& addresses,
203 NetLog* /* net_log */,
[email protected]46fadfd2013-02-06 09:40:16204 const NetLog::Source& /*source*/) OVERRIDE {
[email protected]f6d1d6eb2009-06-24 20:16:09205 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05206 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09207 }
208
209 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18210 ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27211 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21212 const SSLConfig& ssl_config,
[email protected]46fadfd2013-02-06 09:40:16213 const SSLClientSocketContext& context) OVERRIDE {
[email protected]f6d1d6eb2009-06-24 20:16:09214 NOTIMPLEMENTED();
215 return NULL;
216 }
217
[email protected]46fadfd2013-02-06 09:40:16218 virtual void ClearSSLSessionCache() OVERRIDE {
[email protected]25f47352011-02-25 16:31:59219 NOTIMPLEMENTED();
220 }
221
[email protected]5fc08e32009-07-15 17:09:57222 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
223 void SignalJobs();
224
[email protected]f6d1d6eb2009-06-24 20:16:09225 int allocation_count() const { return allocation_count_; }
226
[email protected]f6d1d6eb2009-06-24 20:16:09227 private:
228 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57229 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09230};
231
[email protected]ab838892009-06-30 18:49:05232class TestConnectJob : public ConnectJob {
233 public:
234 enum JobType {
235 kMockJob,
236 kMockFailingJob,
237 kMockPendingJob,
238 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57239 kMockWaitingJob,
240 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13241 kMockRecoverableJob,
242 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18243 kMockAdditionalErrorStateJob,
244 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05245 };
246
[email protected]994d4932010-07-12 17:55:13247 // The kMockPendingJob uses a slight delay before allowing the connect
248 // to complete.
249 static const int kPendingConnectDelay = 2;
250
[email protected]ab838892009-06-30 18:49:05251 TestConnectJob(JobType job_type,
252 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49253 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34254 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05255 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30256 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17257 NetLog* net_log)
258 : ConnectJob(group_name, timeout_duration, delegate,
259 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58260 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05261 client_socket_factory_(client_socket_factory),
[email protected]aa249b52013-04-30 01:04:32262 weak_factory_(this),
[email protected]e60e47a2010-07-14 03:37:18263 load_state_(LOAD_STATE_IDLE),
264 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05265
[email protected]974ebd62009-08-03 23:14:34266 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13267 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34268 }
269
[email protected]46fadfd2013-02-06 09:40:16270 virtual LoadState GetLoadState() const OVERRIDE { return load_state_; }
[email protected]46451352009-09-01 14:54:21271
[email protected]46fadfd2013-02-06 09:40:16272 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) OVERRIDE {
[email protected]e60e47a2010-07-14 03:37:18273 if (store_additional_error_state_) {
274 // Set all of the additional error state fields in some way.
275 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43276 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45277 info.headers = new HttpResponseHeaders(std::string());
[email protected]8b498692010-07-16 17:11:43278 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18279 }
280 }
281
[email protected]974ebd62009-08-03 23:14:34282 private:
[email protected]3f55aa12011-12-07 02:03:33283 // ConnectJob implementation.
[email protected]ab838892009-06-30 18:49:05284
[email protected]46fadfd2013-02-06 09:40:16285 virtual int ConnectInternal() OVERRIDE {
[email protected]ab838892009-06-30 18:49:05286 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28287 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07288 ignored, NULL, net::NetLog::Source());
[email protected]034df0f32013-01-07 23:17:48289 set_socket(new MockClientSocket(net_log().net_log()));
[email protected]ab838892009-06-30 18:49:05290 switch (job_type_) {
291 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13292 return DoConnect(true /* successful */, false /* sync */,
293 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05294 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13295 return DoConnect(false /* error */, false /* sync */,
296 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05297 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57298 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47299
300 // Depending on execution timings, posting a delayed task can result
301 // in the task getting executed the at the earliest possible
302 // opportunity or only after returning once from the message loop and
303 // then a second call into the message loop. In order to make behavior
304 // more deterministic, we change the default delay to 2ms. This should
305 // always require us to wait for the second call into the message loop.
306 //
307 // N.B. The correct fix for this and similar timing problems is to
308 // abstract time for the purpose of unittests. Unfortunately, we have
309 // a lot of third-party components that directly call the various
310 // time functions, so this change would be rather invasive.
311 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05312 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13313 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
314 weak_factory_.GetWeakPtr(),
315 true /* successful */,
316 true /* async */,
317 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53318 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05319 return ERR_IO_PENDING;
320 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57321 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47322 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05323 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13324 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
325 weak_factory_.GetWeakPtr(),
326 false /* error */,
327 true /* async */,
328 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53329 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05330 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57331 case kMockWaitingJob:
332 client_socket_factory_->WaitForSignal(this);
333 waiting_success_ = true;
334 return ERR_IO_PENDING;
335 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46336 MessageLoop::current()->PostTask(
[email protected]6ea7b152011-12-21 21:21:13337 FROM_HERE, base::Bind(&TestConnectJob::AdvanceLoadState,
338 weak_factory_.GetWeakPtr(), load_state_));
[email protected]5fc08e32009-07-15 17:09:57339 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13340 case kMockRecoverableJob:
341 return DoConnect(false /* error */, false /* sync */,
342 true /* recoverable */);
343 case kMockPendingRecoverableJob:
344 set_load_state(LOAD_STATE_CONNECTING);
345 MessageLoop::current()->PostDelayedTask(
346 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13347 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
348 weak_factory_.GetWeakPtr(),
349 false /* error */,
350 true /* async */,
351 true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53352 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13353 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18354 case kMockAdditionalErrorStateJob:
355 store_additional_error_state_ = true;
356 return DoConnect(false /* error */, false /* sync */,
357 false /* recoverable */);
358 case kMockPendingAdditionalErrorStateJob:
359 set_load_state(LOAD_STATE_CONNECTING);
360 store_additional_error_state_ = true;
361 MessageLoop::current()->PostDelayedTask(
362 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13363 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
364 weak_factory_.GetWeakPtr(),
365 false /* error */,
366 true /* async */,
367 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53368 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18369 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05370 default:
371 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40372 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05373 return ERR_FAILED;
374 }
375 }
376
[email protected]46451352009-09-01 14:54:21377 void set_load_state(LoadState load_state) { load_state_ = load_state; }
378
[email protected]e772db3f2010-07-12 18:11:13379 int DoConnect(bool succeed, bool was_async, bool recoverable) {
380 int result = OK;
[email protected]ab838892009-06-30 18:49:05381 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55382 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13383 } else if (recoverable) {
384 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40385 } else {
[email protected]e772db3f2010-07-12 18:11:13386 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40387 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05388 }
[email protected]2ab05b52009-07-01 23:57:58389
390 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30391 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05392 return result;
393 }
394
[email protected]cfa8228c2010-06-17 01:07:56395 // This function helps simulate the progress of load states on a ConnectJob.
396 // Each time it is called it advances the load state and posts a task to be
397 // called again. It stops at the last connecting load state (the one
398 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57399 void AdvanceLoadState(LoadState state) {
400 int tmp = state;
401 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56402 if (tmp < LOAD_STATE_SENDING_REQUEST) {
403 state = static_cast<LoadState>(tmp);
404 set_load_state(state);
405 MessageLoop::current()->PostTask(
[email protected]6ea7b152011-12-21 21:21:13406 FROM_HERE, base::Bind(&TestConnectJob::AdvanceLoadState,
407 weak_factory_.GetWeakPtr(), state));
[email protected]cfa8228c2010-06-17 01:07:56408 }
[email protected]5fc08e32009-07-15 17:09:57409 }
410
411 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05412 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57413 MockClientSocketFactory* const client_socket_factory_;
[email protected]6ea7b152011-12-21 21:21:13414 base::WeakPtrFactory<TestConnectJob> weak_factory_;
[email protected]46451352009-09-01 14:54:21415 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18416 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05417
418 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
419};
420
[email protected]d80a4322009-08-14 07:07:49421class TestConnectJobFactory
422 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05423 public:
[email protected]034df0f32013-01-07 23:17:48424 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
425 NetLog* net_log)
[email protected]ab838892009-06-30 18:49:05426 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48427 job_types_(NULL),
[email protected]034df0f32013-01-07 23:17:48428 client_socket_factory_(client_socket_factory),
429 net_log_(net_log) {
430}
[email protected]ab838892009-06-30 18:49:05431
432 virtual ~TestConnectJobFactory() {}
433
434 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
435
[email protected]51fdc7c2012-04-10 19:19:48436 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
437 job_types_ = job_types;
438 CHECK(!job_types_->empty());
439 }
440
[email protected]974ebd62009-08-03 23:14:34441 void set_timeout_duration(base::TimeDelta timeout_duration) {
442 timeout_duration_ = timeout_duration;
443 }
444
[email protected]3f55aa12011-12-07 02:03:33445 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55446
[email protected]ab838892009-06-30 18:49:05447 virtual ConnectJob* NewConnectJob(
448 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49449 const TestClientSocketPoolBase::Request& request,
[email protected]46fadfd2013-02-06 09:40:16450 ConnectJob::Delegate* delegate) const OVERRIDE {
[email protected]51fdc7c2012-04-10 19:19:48451 EXPECT_TRUE(!job_types_ || !job_types_->empty());
452 TestConnectJob::JobType job_type = job_type_;
453 if (job_types_ && !job_types_->empty()) {
454 job_type = job_types_->front();
455 job_types_->pop_front();
456 }
457 return new TestConnectJob(job_type,
[email protected]ab838892009-06-30 18:49:05458 group_name,
459 request,
[email protected]974ebd62009-08-03 23:14:34460 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05461 delegate,
[email protected]fd7b7c92009-08-20 19:38:30462 client_socket_factory_,
[email protected]034df0f32013-01-07 23:17:48463 net_log_);
[email protected]ab838892009-06-30 18:49:05464 }
465
[email protected]46fadfd2013-02-06 09:40:16466 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE {
[email protected]a796bcec2010-03-22 17:17:26467 return timeout_duration_;
468 }
469
[email protected]ab838892009-06-30 18:49:05470 private:
471 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48472 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34473 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57474 MockClientSocketFactory* const client_socket_factory_;
[email protected]034df0f32013-01-07 23:17:48475 NetLog* net_log_;
[email protected]ab838892009-06-30 18:49:05476
477 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
478};
479
480class TestClientSocketPool : public ClientSocketPool {
481 public:
482 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53483 int max_sockets,
[email protected]ab838892009-06-30 18:49:05484 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13485 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16486 base::TimeDelta unused_idle_socket_timeout,
487 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49488 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00489 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16490 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38491 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05492
[email protected]2431756e2010-09-29 20:26:13493 virtual ~TestClientSocketPool() {}
494
[email protected]ab838892009-06-30 18:49:05495 virtual int RequestSocket(
496 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49497 const void* params,
[email protected]ac790b42009-12-02 04:31:31498 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05499 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41500 const CompletionCallback& callback,
[email protected]d4dfdab2011-12-07 16:56:59501 const BoundNetLog& net_log) OVERRIDE {
[email protected]df4b4ef2010-07-12 18:25:21502 const scoped_refptr<TestSocketParams>* casted_socket_params =
503 static_cast<const scoped_refptr<TestSocketParams>*>(params);
504 return base_.RequestSocket(group_name, *casted_socket_params, priority,
505 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05506 }
507
[email protected]2c2bef152010-10-13 00:55:03508 virtual void RequestSockets(const std::string& group_name,
509 const void* params,
510 int num_sockets,
[email protected]d4dfdab2011-12-07 16:56:59511 const BoundNetLog& net_log) OVERRIDE {
[email protected]2c2bef152010-10-13 00:55:03512 const scoped_refptr<TestSocketParams>* casted_params =
513 static_cast<const scoped_refptr<TestSocketParams>*>(params);
514
515 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
516 }
517
[email protected]ab838892009-06-30 18:49:05518 virtual void CancelRequest(
519 const std::string& group_name,
[email protected]d4dfdab2011-12-07 16:56:59520 ClientSocketHandle* handle) OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49521 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05522 }
523
524 virtual void ReleaseSocket(
525 const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10526 StreamSocket* socket,
[email protected]d4dfdab2011-12-07 16:56:59527 int id) OVERRIDE {
[email protected]a7e38572010-06-07 18:22:24528 base_.ReleaseSocket(group_name, socket, id);
529 }
530
[email protected]7af985a2012-12-14 22:40:42531 virtual void FlushWithError(int error) OVERRIDE {
532 base_.FlushWithError(error);
[email protected]ab838892009-06-30 18:49:05533 }
534
[email protected]51fdc7c2012-04-10 19:19:48535 virtual bool IsStalled() const OVERRIDE {
536 return base_.IsStalled();
537 }
538
[email protected]d4dfdab2011-12-07 16:56:59539 virtual void CloseIdleSockets() OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49540 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05541 }
542
[email protected]d4dfdab2011-12-07 16:56:59543 virtual int IdleSocketCount() const OVERRIDE {
544 return base_.idle_socket_count();
545 }
[email protected]ab838892009-06-30 18:49:05546
[email protected]d4dfdab2011-12-07 16:56:59547 virtual int IdleSocketCountInGroup(
548 const std::string& group_name) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49549 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05550 }
551
[email protected]d4dfdab2011-12-07 16:56:59552 virtual LoadState GetLoadState(
553 const std::string& group_name,
554 const ClientSocketHandle* handle) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49555 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05556 }
557
[email protected]51fdc7c2012-04-10 19:19:48558 virtual void AddLayeredPool(LayeredPool* pool) OVERRIDE {
559 base_.AddLayeredPool(pool);
560 }
561
562 virtual void RemoveLayeredPool(LayeredPool* pool) OVERRIDE {
563 base_.RemoveLayeredPool(pool);
564 }
565
[email protected]d4dfdab2011-12-07 16:56:59566 virtual DictionaryValue* GetInfoAsValue(
567 const std::string& name,
568 const std::string& type,
569 bool include_nested_pools) const OVERRIDE {
[email protected]59d7a5a2010-08-30 16:44:27570 return base_.GetInfoAsValue(name, type);
571 }
572
[email protected]d4dfdab2011-12-07 16:56:59573 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE {
[email protected]a796bcec2010-03-22 17:17:26574 return base_.ConnectionTimeout();
575 }
576
[email protected]d4dfdab2011-12-07 16:56:59577 virtual ClientSocketPoolHistograms* histograms() const OVERRIDE {
[email protected]b89f7e42010-05-20 20:37:00578 return base_.histograms();
579 }
[email protected]a796bcec2010-03-22 17:17:26580
[email protected]d80a4322009-08-14 07:07:49581 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20582
[email protected]8159a1c2012-06-07 00:00:10583 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
584 return base_.NumUnassignedConnectJobsInGroup(group_name);
585 }
586
[email protected]974ebd62009-08-03 23:14:34587 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49588 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34589 }
590
[email protected]2c2bef152010-10-13 00:55:03591 int NumActiveSocketsInGroup(const std::string& group_name) const {
592 return base_.NumActiveSocketsInGroup(group_name);
593 }
594
[email protected]2abfe90a2010-08-25 17:49:51595 bool HasGroup(const std::string& group_name) const {
596 return base_.HasGroup(group_name);
597 }
598
[email protected]9bf28db2009-08-29 01:35:16599 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
600
[email protected]06d94042010-08-25 01:45:22601 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54602
[email protected]51fdc7c2012-04-10 19:19:48603 bool CloseOneIdleConnectionInLayeredPool() {
604 return base_.CloseOneIdleConnectionInLayeredPool();
605 }
606
[email protected]ab838892009-06-30 18:49:05607 private:
[email protected]d80a4322009-08-14 07:07:49608 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05609
610 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
611};
612
[email protected]a937a06d2009-08-19 21:19:24613} // namespace
614
[email protected]7fc5b09a2010-02-27 00:07:38615REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24616
617namespace {
618
[email protected]5fc08e32009-07-15 17:09:57619void MockClientSocketFactory::SignalJobs() {
620 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
621 it != waiting_jobs_.end(); ++it) {
622 (*it)->Signal();
623 }
624 waiting_jobs_.clear();
625}
626
[email protected]974ebd62009-08-03 23:14:34627class TestConnectJobDelegate : public ConnectJob::Delegate {
628 public:
629 TestConnectJobDelegate()
630 : have_result_(false), waiting_for_result_(false), result_(OK) {}
631 virtual ~TestConnectJobDelegate() {}
632
[email protected]46fadfd2013-02-06 09:40:16633 virtual void OnConnectJobComplete(int result, ConnectJob* job) OVERRIDE {
[email protected]974ebd62009-08-03 23:14:34634 result_ = result;
[email protected]3268023f2011-05-05 00:08:10635 scoped_ptr<StreamSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07636 // socket.get() should be NULL iff result != OK
637 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34638 delete job;
639 have_result_ = true;
640 if (waiting_for_result_)
641 MessageLoop::current()->Quit();
642 }
643
644 int WaitForResult() {
645 DCHECK(!waiting_for_result_);
646 while (!have_result_) {
647 waiting_for_result_ = true;
648 MessageLoop::current()->Run();
649 waiting_for_result_ = false;
650 }
651 have_result_ = false; // auto-reset for next callback
652 return result_;
653 }
654
655 private:
656 bool have_result_;
657 bool waiting_for_result_;
658 int result_;
659};
660
[email protected]2431756e2010-09-29 20:26:13661class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09662 protected:
[email protected]b89f7e42010-05-20 20:37:00663 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21664 : params_(new TestSocketParams()),
[email protected]636b8252011-04-08 19:56:54665 histograms_("ClientSocketPoolTest") {
666 connect_backup_jobs_enabled_ =
667 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
668 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41669 cleanup_timer_enabled_ =
670 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54671 }
[email protected]2431756e2010-09-29 20:26:13672
[email protected]636b8252011-04-08 19:56:54673 virtual ~ClientSocketPoolBaseTest() {
674 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
675 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41676 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
677 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54678 }
[email protected]c9d6a1d2009-07-14 16:15:20679
[email protected]211d21722009-07-22 15:48:53680 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16681 CreatePoolWithIdleTimeouts(
682 max_sockets,
683 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30684 ClientSocketPool::unused_idle_socket_timeout(),
685 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16686 }
687
688 void CreatePoolWithIdleTimeouts(
689 int max_sockets, int max_sockets_per_group,
690 base::TimeDelta unused_idle_socket_timeout,
691 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20692 DCHECK(!pool_.get());
[email protected]034df0f32013-01-07 23:17:48693 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_,
694 &net_log_);
[email protected]2431756e2010-09-29 20:26:13695 pool_.reset(new TestClientSocketPool(max_sockets,
696 max_sockets_per_group,
697 &histograms_,
698 unused_idle_socket_timeout,
699 used_idle_socket_timeout,
700 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20701 }
[email protected]f6d1d6eb2009-06-24 20:16:09702
[email protected]ac790b42009-12-02 04:31:31703 int StartRequest(const std::string& group_name,
704 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13705 return test_base_.StartRequestUsingPool<
706 TestClientSocketPool, TestSocketParams>(
707 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09708 }
709
[email protected]2431756e2010-09-29 20:26:13710 int GetOrderOfRequest(size_t index) const {
711 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09712 }
713
[email protected]2431756e2010-09-29 20:26:13714 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
715 return test_base_.ReleaseOneConnection(keep_alive);
716 }
717
718 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
719 test_base_.ReleaseAllConnections(keep_alive);
720 }
721
722 TestSocketRequest* request(int i) { return test_base_.request(i); }
723 size_t requests_size() const { return test_base_.requests_size(); }
724 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
725 size_t completion_count() const { return test_base_.completion_count(); }
726
[email protected]034df0f32013-01-07 23:17:48727 CapturingNetLog net_log_;
[email protected]636b8252011-04-08 19:56:54728 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41729 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09730 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04731 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21732 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13733 ClientSocketPoolHistograms histograms_;
734 scoped_ptr<TestClientSocketPool> pool_;
735 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09736};
737
[email protected]974ebd62009-08-03 23:14:34738// Even though a timeout is specified, it doesn't time out on a synchronous
739// completion.
740TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
741 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06742 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49743 TestClientSocketPoolBase::Request request(
[email protected]49639fa2011-12-20 23:22:41744 &ignored, CompletionCallback(), kDefaultPriority,
[email protected]2c2bef152010-10-13 00:55:03745 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20746 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34747 scoped_ptr<TestConnectJob> job(
748 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12749 "a",
[email protected]974ebd62009-08-03 23:14:34750 request,
751 base::TimeDelta::FromMicroseconds(1),
752 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30753 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17754 NULL));
[email protected]974ebd62009-08-03 23:14:34755 EXPECT_EQ(OK, job->Connect());
756}
757
758TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
759 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06760 ClientSocketHandle ignored;
[email protected]333bdf62012-06-08 22:57:29761 CapturingNetLog log;
[email protected]9e743cd2010-03-16 07:03:53762
[email protected]d80a4322009-08-14 07:07:49763 TestClientSocketPoolBase::Request request(
[email protected]49639fa2011-12-20 23:22:41764 &ignored, CompletionCallback(), kDefaultPriority,
[email protected]2c2bef152010-10-13 00:55:03765 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20766 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34767 // Deleted by TestConnectJobDelegate.
768 TestConnectJob* job =
769 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12770 "a",
[email protected]974ebd62009-08-03 23:14:34771 request,
772 base::TimeDelta::FromMicroseconds(1),
773 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30774 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17775 &log);
[email protected]974ebd62009-08-03 23:14:34776 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]26b9973962012-01-28 00:57:00777 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
[email protected]974ebd62009-08-03 23:14:34778 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30779
[email protected]333bdf62012-06-08 22:57:29780 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40781 log.GetEntries(&entries);
782
783 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46784 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40785 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17786 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40787 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46788 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40789 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17790 NetLog::PHASE_NONE));
791 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40792 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53793 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46794 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40795 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17796 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40797 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34798}
799
[email protected]5fc08e32009-07-15 17:09:57800TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53801 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20802
[email protected]6ecf2b92011-12-15 01:14:52803 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06804 ClientSocketHandle handle;
[email protected]333bdf62012-06-08 22:57:29805 CapturingBoundNetLog log;
[email protected]034df0f32013-01-07 23:17:48806 TestLoadTimingInfoNotConnected(handle);
[email protected]9e743cd2010-03-16 07:03:53807
[email protected]2431756e2010-09-29 20:26:13808 EXPECT_EQ(OK,
809 handle.Init("a",
810 params_,
811 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:52812 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13813 pool_.get(),
814 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09815 EXPECT_TRUE(handle.is_initialized());
816 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:48817 TestLoadTimingInfoConnectedNotReused(handle);
818
[email protected]f6d1d6eb2009-06-24 20:16:09819 handle.Reset();
[email protected]034df0f32013-01-07 23:17:48820 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30821
[email protected]333bdf62012-06-08 22:57:29822 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40823 log.GetEntries(&entries);
824
825 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46826 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40827 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53828 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40829 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17830 NetLog::PHASE_NONE));
831 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40832 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53833 NetLog::PHASE_NONE));
834 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40835 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09836}
837
[email protected]ab838892009-06-30 18:49:05838TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53839 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20840
[email protected]ab838892009-06-30 18:49:05841 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]333bdf62012-06-08 22:57:29842 CapturingBoundNetLog log;
[email protected]9e743cd2010-03-16 07:03:53843
[email protected]2431756e2010-09-29 20:26:13844 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52845 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18846 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13847 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43848 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:45849 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:13850 handle.set_ssl_error_response_info(info);
851 EXPECT_EQ(ERR_CONNECTION_FAILED,
852 handle.Init("a",
853 params_,
854 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:52855 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13856 pool_.get(),
857 log.bound()));
858 EXPECT_FALSE(handle.socket());
859 EXPECT_FALSE(handle.is_ssl_error());
860 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]034df0f32013-01-07 23:17:48861 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:30862
[email protected]333bdf62012-06-08 22:57:29863 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40864 log.GetEntries(&entries);
865
866 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27867 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40868 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17869 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40870 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17871 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02872 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40873 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09874}
875
[email protected]211d21722009-07-22 15:48:53876TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
877 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
878
[email protected]9e743cd2010-03-16 07:03:53879 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30880
[email protected]211d21722009-07-22 15:48:53881 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
882 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
883 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
884 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
885
[email protected]2431756e2010-09-29 20:26:13886 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53887 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13888 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53889
890 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
891 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
892 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
893
[email protected]2431756e2010-09-29 20:26:13894 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53895
[email protected]2431756e2010-09-29 20:26:13896 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53897 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13898 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53899
900 EXPECT_EQ(1, GetOrderOfRequest(1));
901 EXPECT_EQ(2, GetOrderOfRequest(2));
902 EXPECT_EQ(3, GetOrderOfRequest(3));
903 EXPECT_EQ(4, GetOrderOfRequest(4));
904 EXPECT_EQ(5, GetOrderOfRequest(5));
905 EXPECT_EQ(6, GetOrderOfRequest(6));
906 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17907
908 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13909 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53910}
911
912TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
913 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
914
[email protected]9e743cd2010-03-16 07:03:53915 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30916
[email protected]211d21722009-07-22 15:48:53917 // Reach all limits: max total sockets, and max sockets per group.
918 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
919 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
920 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
921 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
922
[email protected]2431756e2010-09-29 20:26:13923 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53924 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13925 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53926
927 // Now create a new group and verify that we don't starve it.
928 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
929
[email protected]2431756e2010-09-29 20:26:13930 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53931
[email protected]2431756e2010-09-29 20:26:13932 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53933 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13934 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53935
936 EXPECT_EQ(1, GetOrderOfRequest(1));
937 EXPECT_EQ(2, GetOrderOfRequest(2));
938 EXPECT_EQ(3, GetOrderOfRequest(3));
939 EXPECT_EQ(4, GetOrderOfRequest(4));
940 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17941
942 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13943 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53944}
945
946TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
947 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
948
[email protected]ac790b42009-12-02 04:31:31949 EXPECT_EQ(OK, StartRequest("b", LOWEST));
950 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
951 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
952 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53953
[email protected]2431756e2010-09-29 20:26:13954 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53955 client_socket_factory_.allocation_count());
956
[email protected]ac790b42009-12-02 04:31:31957 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
958 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
959 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53960
[email protected]2431756e2010-09-29 20:26:13961 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53962
[email protected]2431756e2010-09-29 20:26:13963 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53964
965 // First 4 requests don't have to wait, and finish in order.
966 EXPECT_EQ(1, GetOrderOfRequest(1));
967 EXPECT_EQ(2, GetOrderOfRequest(2));
968 EXPECT_EQ(3, GetOrderOfRequest(3));
969 EXPECT_EQ(4, GetOrderOfRequest(4));
970
[email protected]ac790b42009-12-02 04:31:31971 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
972 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53973 EXPECT_EQ(7, GetOrderOfRequest(5));
974 EXPECT_EQ(6, GetOrderOfRequest(6));
975 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17976
977 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13978 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53979}
980
981TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
982 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
983
[email protected]ac790b42009-12-02 04:31:31984 EXPECT_EQ(OK, StartRequest("a", LOWEST));
985 EXPECT_EQ(OK, StartRequest("a", LOW));
986 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
987 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53988
[email protected]2431756e2010-09-29 20:26:13989 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53990 client_socket_factory_.allocation_count());
991
[email protected]ac790b42009-12-02 04:31:31992 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
993 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
994 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53995
[email protected]2431756e2010-09-29 20:26:13996 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53997
[email protected]2431756e2010-09-29 20:26:13998 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53999 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131000 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531001
1002 // First 4 requests don't have to wait, and finish in order.
1003 EXPECT_EQ(1, GetOrderOfRequest(1));
1004 EXPECT_EQ(2, GetOrderOfRequest(2));
1005 EXPECT_EQ(3, GetOrderOfRequest(3));
1006 EXPECT_EQ(4, GetOrderOfRequest(4));
1007
1008 // Request ("b", 7) has the highest priority, but we can't make new socket for
1009 // group "b", because it has reached the per-group limit. Then we make
1010 // socket for ("c", 6), because it has higher priority than ("a", 4),
1011 // and we still can't make a socket for group "b".
1012 EXPECT_EQ(5, GetOrderOfRequest(5));
1013 EXPECT_EQ(6, GetOrderOfRequest(6));
1014 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171015
1016 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131017 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531018}
1019
1020// Make sure that we count connecting sockets against the total limit.
1021TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1022 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1023
1024 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1025 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1026 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
1027
1028 // Create one asynchronous request.
1029 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1030 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
1031
[email protected]6b175382009-10-13 06:47:471032 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1033 // actually become pending until 2ms after they have been created. In order
1034 // to flush all tasks, we need to wait so that we know there are no
1035 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001036 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]b4c62eb2012-11-14 18:36:511037 MessageLoop::current()->RunUntilIdle();
[email protected]6b175382009-10-13 06:47:471038
[email protected]211d21722009-07-22 15:48:531039 // The next synchronous request should wait for its turn.
1040 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1041 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
1042
[email protected]2431756e2010-09-29 20:26:131043 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531044
[email protected]2431756e2010-09-29 20:26:131045 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531046 client_socket_factory_.allocation_count());
1047
1048 EXPECT_EQ(1, GetOrderOfRequest(1));
1049 EXPECT_EQ(2, GetOrderOfRequest(2));
1050 EXPECT_EQ(3, GetOrderOfRequest(3));
1051 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171052 EXPECT_EQ(5, GetOrderOfRequest(5));
1053
1054 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131055 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531056}
1057
[email protected]6427fe22010-04-16 22:27:411058TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1059 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1060 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1061
1062 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1063 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1064 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1065 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1066
1067 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1068
1069 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1070
1071 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
1072 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
1073
1074 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1075
[email protected]2431756e2010-09-29 20:26:131076 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411077 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131078 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411079 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131080 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1081 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411082 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1083}
1084
[email protected]d7027bb2010-05-10 18:58:541085TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1086 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1087 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1088
1089 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521090 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131091 EXPECT_EQ(ERR_IO_PENDING,
1092 handle.Init("a",
1093 params_,
1094 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521095 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131096 pool_.get(),
1097 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541098
1099 ClientSocketHandle handles[4];
1100 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521101 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131102 EXPECT_EQ(ERR_IO_PENDING,
1103 handles[i].Init("b",
1104 params_,
1105 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521106 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131107 pool_.get(),
1108 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541109 }
1110
1111 // One will be stalled, cancel all the handles now.
1112 // This should hit the OnAvailableSocketSlot() code where we previously had
1113 // stalled groups, but no longer have any.
1114 for (size_t i = 0; i < arraysize(handles); ++i)
1115 handles[i].Reset();
1116}
1117
[email protected]eb5a99382010-07-11 03:18:261118TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541119 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1120 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1121
[email protected]eb5a99382010-07-11 03:18:261122 {
1123 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521124 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261125 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131126 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1127 params_,
[email protected]e83326f2010-07-31 17:29:251128 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521129 callbacks[i].callback(),
[email protected]2431756e2010-09-29 20:26:131130 pool_.get(),
1131 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261132 }
1133
1134 // Force a stalled group.
1135 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521136 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131137 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1138 params_,
1139 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521140 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131141 pool_.get(),
1142 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261143
1144 // Cancel the stalled request.
1145 stalled_handle.Reset();
1146
1147 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1148 EXPECT_EQ(0, pool_->IdleSocketCount());
1149
1150 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541151 }
1152
[email protected]43a21b82010-06-10 21:30:541153 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1154 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261155}
[email protected]43a21b82010-06-10 21:30:541156
[email protected]eb5a99382010-07-11 03:18:261157TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1158 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1159 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1160
1161 {
1162 ClientSocketHandle handles[kDefaultMaxSockets];
1163 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521164 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131165 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1166 params_,
1167 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521168 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131169 pool_.get(),
1170 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261171 }
1172
1173 // Force a stalled group.
1174 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1175 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521176 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131177 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1178 params_,
1179 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521180 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131181 pool_.get(),
1182 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261183
1184 // Since it is stalled, it should have no connect jobs.
1185 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101186 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261187
1188 // Cancel the stalled request.
1189 handles[0].Reset();
1190
[email protected]eb5a99382010-07-11 03:18:261191 // Now we should have a connect job.
1192 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101193 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261194
1195 // The stalled socket should connect.
1196 EXPECT_EQ(OK, callback.WaitForResult());
1197
1198 EXPECT_EQ(kDefaultMaxSockets + 1,
1199 client_socket_factory_.allocation_count());
1200 EXPECT_EQ(0, pool_->IdleSocketCount());
1201 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101202 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261203
1204 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541205 }
1206
[email protected]eb5a99382010-07-11 03:18:261207 EXPECT_EQ(1, pool_->IdleSocketCount());
1208}
[email protected]43a21b82010-06-10 21:30:541209
[email protected]eb5a99382010-07-11 03:18:261210TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1211 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1212 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541213
[email protected]eb5a99382010-07-11 03:18:261214 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521215 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261216 {
[email protected]51fdc7c2012-04-10 19:19:481217 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261218 ClientSocketHandle handles[kDefaultMaxSockets];
1219 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521220 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401221 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1222 "Take 2: %d", i),
1223 params_,
1224 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521225 callback.callback(),
[email protected]1870d5cf2011-05-12 01:55:401226 pool_.get(),
1227 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261228 }
1229
1230 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1231 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481232 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261233
1234 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131235 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1236 params_,
1237 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521238 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131239 pool_.get(),
1240 BoundNetLog()));
[email protected]51fdc7c2012-04-10 19:19:481241 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261242
1243 // Dropping out of scope will close all handles and return them to idle.
1244 }
[email protected]43a21b82010-06-10 21:30:541245
1246 // But if we wait for it, the released idle sockets will be closed in
1247 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101248 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261249
1250 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1251 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541252}
1253
1254// Regression test for http://crbug.com/40952.
1255TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1256 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221257 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541258 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1259
1260 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1261 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521262 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131263 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1264 params_,
1265 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521266 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131267 pool_.get(),
1268 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541269 }
1270
1271 // Flush all the DoReleaseSocket tasks.
[email protected]b4c62eb2012-11-14 18:36:511272 MessageLoop::current()->RunUntilIdle();
[email protected]43a21b82010-06-10 21:30:541273
1274 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1275 // reuse a socket.
1276 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1277 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521278 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541279
1280 // "0" is special here, since it should be the first entry in the sorted map,
1281 // which is the one which we would close an idle socket for. We shouldn't
1282 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131283 EXPECT_EQ(OK, handle.Init("0",
1284 params_,
1285 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521286 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131287 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211288 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541289
1290 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1291 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1292}
1293
[email protected]ab838892009-06-30 18:49:051294TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531295 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091296
[email protected]c9d6a1d2009-07-14 16:15:201297 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1298 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031299 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311300 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1301 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1302 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1303 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1304 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091305
[email protected]2431756e2010-09-29 20:26:131306 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091307
[email protected]c9d6a1d2009-07-14 16:15:201308 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1309 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131310 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1311 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091312
[email protected]c9d6a1d2009-07-14 16:15:201313 EXPECT_EQ(1, GetOrderOfRequest(1));
1314 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031315 EXPECT_EQ(8, GetOrderOfRequest(3));
1316 EXPECT_EQ(6, GetOrderOfRequest(4));
1317 EXPECT_EQ(4, GetOrderOfRequest(5));
1318 EXPECT_EQ(3, GetOrderOfRequest(6));
1319 EXPECT_EQ(5, GetOrderOfRequest(7));
1320 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171321
1322 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131323 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091324}
1325
[email protected]ab838892009-06-30 18:49:051326TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531327 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091328
[email protected]c9d6a1d2009-07-14 16:15:201329 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1330 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311331 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1332 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1333 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1334 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1335 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091336
[email protected]2431756e2010-09-29 20:26:131337 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091338
[email protected]2431756e2010-09-29 20:26:131339 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1340 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201341
[email protected]2431756e2010-09-29 20:26:131342 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201343 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131344 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1345 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091346}
1347
1348// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051349// The pending connect job will be cancelled and should not call back into
1350// ClientSocketPoolBase.
1351TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531352 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201353
[email protected]ab838892009-06-30 18:49:051354 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131355 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521356 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131357 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1358 params_,
1359 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521360 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131361 pool_.get(),
1362 BoundNetLog()));
1363 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091364}
1365
[email protected]ab838892009-06-30 18:49:051366TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531367 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201368
[email protected]ab838892009-06-30 18:49:051369 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061370 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521371 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091372
[email protected]2431756e2010-09-29 20:26:131373 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1374 params_,
1375 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521376 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131377 pool_.get(),
1378 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091379
1380 handle.Reset();
1381
[email protected]6ecf2b92011-12-15 01:14:521382 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131383 EXPECT_EQ(ERR_IO_PENDING,
1384 handle.Init("a",
1385 params_,
1386 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521387 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131388 pool_.get(),
1389 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091390
1391 EXPECT_EQ(OK, callback2.WaitForResult());
1392 EXPECT_FALSE(callback.have_result());
1393
1394 handle.Reset();
1395}
1396
[email protected]ab838892009-06-30 18:49:051397TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531398 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091399
[email protected]c9d6a1d2009-07-14 16:15:201400 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1401 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311402 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1403 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1404 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1405 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1406 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091407
1408 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201409 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131410 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1411 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091412
[email protected]2431756e2010-09-29 20:26:131413 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091414
[email protected]c9d6a1d2009-07-14 16:15:201415 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1416 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131417 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1418 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091419
[email protected]c9d6a1d2009-07-14 16:15:201420 EXPECT_EQ(1, GetOrderOfRequest(1));
1421 EXPECT_EQ(2, GetOrderOfRequest(2));
1422 EXPECT_EQ(5, GetOrderOfRequest(3));
1423 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131424 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1425 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201426 EXPECT_EQ(4, GetOrderOfRequest(6));
1427 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171428
1429 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131430 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091431}
1432
[email protected]6ecf2b92011-12-15 01:14:521433class RequestSocketCallback : public TestCompletionCallbackBase {
[email protected]f6d1d6eb2009-06-24 20:16:091434 public:
[email protected]2ab05b52009-07-01 23:57:581435 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241436 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581437 TestConnectJobFactory* test_connect_job_factory,
1438 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091439 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061440 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581441 within_callback_(false),
1442 test_connect_job_factory_(test_connect_job_factory),
[email protected]6ecf2b92011-12-15 01:14:521443 next_job_type_(next_job_type),
[email protected]aa249b52013-04-30 01:04:321444 callback_(base::Bind(&RequestSocketCallback::OnComplete,
1445 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:521446 }
[email protected]f6d1d6eb2009-06-24 20:16:091447
[email protected]6ecf2b92011-12-15 01:14:521448 virtual ~RequestSocketCallback() {}
1449
1450 const CompletionCallback& callback() const { return callback_; }
1451
1452 private:
1453 void OnComplete(int result) {
1454 SetResult(result);
1455 ASSERT_EQ(OK, result);
[email protected]f6d1d6eb2009-06-24 20:16:091456
1457 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581458 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111459
1460 // Don't allow reuse of the socket. Disconnect it and then release it and
1461 // run through the MessageLoop once to get it completely released.
1462 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091463 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111464 {
[email protected]b5717a42012-02-14 19:33:521465 // TODO: Resolve conflicting intentions of stopping recursion with the
[email protected]b4c62eb2012-11-14 18:36:511466 // |!within_callback_| test (above) and the call to |RunUntilIdle()|
[email protected]b5717a42012-02-14 19:33:521467 // below. http://crbug.com/114130.
1468 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
[email protected]b4c62eb2012-11-14 18:36:511469 MessageLoop::current()->RunUntilIdle();
[email protected]5edbf8d2010-01-13 18:44:111470 }
[email protected]f6d1d6eb2009-06-24 20:16:091471 within_callback_ = true;
[email protected]6ecf2b92011-12-15 01:14:521472 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271473 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131474 int rv = handle_->Init("a",
1475 params,
1476 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521477 next_job_callback.callback(),
[email protected]2431756e2010-09-29 20:26:131478 pool_,
1479 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581480 switch (next_job_type_) {
1481 case TestConnectJob::kMockJob:
1482 EXPECT_EQ(OK, rv);
1483 break;
1484 case TestConnectJob::kMockPendingJob:
1485 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471486
1487 // For pending jobs, wait for new socket to be created. This makes
1488 // sure there are no more pending operations nor any unclosed sockets
1489 // when the test finishes.
1490 // We need to give it a little bit of time to run, so that all the
1491 // operations that happen on timers (e.g. cleanup of idle
1492 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111493 {
[email protected]b5717a42012-02-14 19:33:521494 MessageLoop::ScopedNestableTaskAllower allow(
[email protected]5edbf8d2010-01-13 18:44:111495 MessageLoop::current());
[email protected]26b9973962012-01-28 00:57:001496 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]5edbf8d2010-01-13 18:44:111497 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1498 }
[email protected]2ab05b52009-07-01 23:57:581499 break;
1500 default:
1501 FAIL() << "Unexpected job type: " << next_job_type_;
1502 break;
1503 }
[email protected]f6d1d6eb2009-06-24 20:16:091504 }
1505 }
1506
[email protected]f6d1d6eb2009-06-24 20:16:091507 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131508 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091509 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581510 TestConnectJobFactory* const test_connect_job_factory_;
1511 TestConnectJob::JobType next_job_type_;
[email protected]6ecf2b92011-12-15 01:14:521512 CompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091513};
1514
[email protected]2ab05b52009-07-01 23:57:581515TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531516 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201517
[email protected]0b7648c2009-07-06 20:14:011518 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061519 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581520 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061521 &handle, pool_.get(), connect_job_factory_,
1522 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131523 int rv = handle.Init("a",
1524 params_,
1525 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521526 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131527 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211528 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091529 ASSERT_EQ(ERR_IO_PENDING, rv);
1530
1531 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581532}
[email protected]f6d1d6eb2009-06-24 20:16:091533
[email protected]2ab05b52009-07-01 23:57:581534TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531535 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201536
[email protected]0b7648c2009-07-06 20:14:011537 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061538 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581539 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061540 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131541 int rv = handle.Init("a",
1542 params_,
1543 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521544 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131545 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211546 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581547 ASSERT_EQ(ERR_IO_PENDING, rv);
1548
1549 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091550}
1551
1552// Make sure that pending requests get serviced after active requests get
1553// cancelled.
[email protected]ab838892009-06-30 18:49:051554TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531555 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201556
[email protected]0b7648c2009-07-06 20:14:011557 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091558
[email protected]c9d6a1d2009-07-14 16:15:201559 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1560 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1561 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1562 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1563 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1564 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1565 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091566
[email protected]c9d6a1d2009-07-14 16:15:201567 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1568 // Let's cancel them.
1569 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131570 ASSERT_FALSE(request(i)->handle()->is_initialized());
1571 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091572 }
1573
[email protected]f6d1d6eb2009-06-24 20:16:091574 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131575 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1576 EXPECT_EQ(OK, request(i)->WaitForResult());
1577 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091578 }
1579
[email protected]2431756e2010-09-29 20:26:131580 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1581 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091582}
1583
1584// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051585TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531586 const size_t kMaxSockets = 5;
1587 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201588
[email protected]0b7648c2009-07-06 20:14:011589 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091590
[email protected]211d21722009-07-22 15:48:531591 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1592 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091593
1594 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531595 for (size_t i = 0; i < kNumberOfRequests; ++i)
1596 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091597
[email protected]211d21722009-07-22 15:48:531598 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131599 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091600}
1601
[email protected]5fc08e32009-07-15 17:09:571602TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531603 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571604
1605 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1606
[email protected]2431756e2010-09-29 20:26:131607 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521608 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131609 int rv = handle.Init("a",
1610 params_,
1611 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521612 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131613 pool_.get(),
1614 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571615 EXPECT_EQ(ERR_IO_PENDING, rv);
1616
1617 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131618 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571619
[email protected]2431756e2010-09-29 20:26:131620 rv = handle.Init("a",
1621 params_,
1622 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521623 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131624 pool_.get(),
1625 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571626 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131627 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571628
[email protected]2431756e2010-09-29 20:26:131629 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481630 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571631 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1632}
1633
[email protected]2b7523d2009-07-29 20:29:231634// Regression test for http://crbug.com/17985.
1635TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1636 const int kMaxSockets = 3;
1637 const int kMaxSocketsPerGroup = 2;
1638 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1639
[email protected]ac790b42009-12-02 04:31:311640 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231641
1642 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1643 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1644
1645 // This is going to be a pending request in an otherwise empty group.
1646 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1647
1648 // Reach the maximum socket limit.
1649 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1650
1651 // Create a stalled group with high priorities.
1652 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1653 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231654
[email protected]eb5a99382010-07-11 03:18:261655 // Release the first two sockets from "a". Because this is a keepalive,
1656 // the first release will unblock the pending request for "a". The
1657 // second release will unblock a request for "c", becaue it is the next
1658 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131659 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1660 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231661
1662 // Closing idle sockets should not get us into trouble, but in the bug
1663 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411664 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541665 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261666
[email protected]b4c62eb2012-11-14 18:36:511667 MessageLoop::current()->RunUntilIdle(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231668}
1669
[email protected]4d3b05d2010-01-27 21:27:291670TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531671 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571672
1673 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131674 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521675 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291676 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:131677 int rv = handle.Init("a",
1678 params_,
1679 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521680 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131681 pool_.get(),
1682 log.bound());
[email protected]5fc08e32009-07-15 17:09:571683 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131684 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481685 TestLoadTimingInfoNotConnected(handle);
1686
[email protected]2431756e2010-09-29 20:26:131687 EXPECT_EQ(OK, callback.WaitForResult());
1688 EXPECT_TRUE(handle.is_initialized());
1689 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481690 TestLoadTimingInfoConnectedNotReused(handle);
1691
[email protected]2431756e2010-09-29 20:26:131692 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481693 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301694
[email protected]333bdf62012-06-08 22:57:291695 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401696 log.GetEntries(&entries);
1697
1698 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461699 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401700 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171701 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401702 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171703 NetLog::PHASE_NONE));
1704 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401705 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171706 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461707 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401708 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571709}
1710
[email protected]4d3b05d2010-01-27 21:27:291711TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571712 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531713 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571714
1715 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131716 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521717 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291718 CapturingBoundNetLog log;
[email protected]e60e47a2010-07-14 03:37:181719 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131720 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431721 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451722 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131723 handle.set_ssl_error_response_info(info);
1724 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1725 params_,
1726 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521727 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131728 pool_.get(),
1729 log.bound()));
1730 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1731 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1732 EXPECT_FALSE(handle.is_ssl_error());
1733 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301734
[email protected]333bdf62012-06-08 22:57:291735 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401736 log.GetEntries(&entries);
1737
1738 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461739 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401740 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171741 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401742 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171743 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321744 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401745 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571746}
1747
[email protected]4d3b05d2010-01-27 21:27:291748TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101749 // TODO(eroman): Add back the log expectations! Removed them because the
1750 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531751 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571752
1753 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131754 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521755 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131756 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521757 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571758
[email protected]2431756e2010-09-29 20:26:131759 EXPECT_EQ(ERR_IO_PENDING,
1760 handle.Init("a",
1761 params_,
1762 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521763 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131764 pool_.get(),
1765 BoundNetLog()));
[email protected]333bdf62012-06-08 22:57:291766 CapturingBoundNetLog log2;
[email protected]2431756e2010-09-29 20:26:131767 EXPECT_EQ(ERR_IO_PENDING,
1768 handle2.Init("a",
1769 params_,
1770 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521771 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131772 pool_.get(),
1773 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571774
[email protected]2431756e2010-09-29 20:26:131775 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571776
[email protected]fd7b7c92009-08-20 19:38:301777
1778 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301779
[email protected]2431756e2010-09-29 20:26:131780 EXPECT_EQ(OK, callback2.WaitForResult());
1781 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301782
1783 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531784 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571785}
1786
[email protected]4d3b05d2010-01-27 21:27:291787TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341788 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1789
[email protected]17a0c6c2009-08-04 00:07:041790 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1791
[email protected]ac790b42009-12-02 04:31:311792 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1793 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1794 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1795 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341796
1797 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131798 (*requests())[2]->handle()->Reset();
1799 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341800 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1801
[email protected]2431756e2010-09-29 20:26:131802 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341803 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1804
[email protected]2431756e2010-09-29 20:26:131805 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261806 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341807}
1808
[email protected]5fc08e32009-07-15 17:09:571809// When requests and ConnectJobs are not coupled, the request will get serviced
1810// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291811TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531812 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571813
1814 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321815 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571816
[email protected]2431756e2010-09-29 20:26:131817 std::vector<TestSocketRequest*> request_order;
1818 size_t completion_count; // unused
1819 TestSocketRequest req1(&request_order, &completion_count);
1820 int rv = req1.handle()->Init("a",
1821 params_,
1822 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521823 req1.callback(), pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211824 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571825 EXPECT_EQ(ERR_IO_PENDING, rv);
1826 EXPECT_EQ(OK, req1.WaitForResult());
1827
1828 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1829 // without a job.
1830 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1831
[email protected]2431756e2010-09-29 20:26:131832 TestSocketRequest req2(&request_order, &completion_count);
1833 rv = req2.handle()->Init("a",
1834 params_,
1835 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521836 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131837 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211838 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571839 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131840 TestSocketRequest req3(&request_order, &completion_count);
1841 rv = req3.handle()->Init("a",
1842 params_,
1843 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521844 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131845 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211846 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571847 EXPECT_EQ(ERR_IO_PENDING, rv);
1848
1849 // Both Requests 2 and 3 are pending. We release socket 1 which should
1850 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331851 req1.handle()->Reset();
[email protected]b4c62eb2012-11-14 18:36:511852 MessageLoop::current()->RunUntilIdle(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331853 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571854 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331855 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571856
1857 // Signal job 2, which should service request 3.
1858
1859 client_socket_factory_.SignalJobs();
1860 EXPECT_EQ(OK, req3.WaitForResult());
1861
[email protected]2431756e2010-09-29 20:26:131862 ASSERT_EQ(3U, request_order.size());
1863 EXPECT_EQ(&req1, request_order[0]);
1864 EXPECT_EQ(&req2, request_order[1]);
1865 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571866 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1867}
1868
1869// The requests are not coupled to the jobs. So, the requests should finish in
1870// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291871TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531872 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571873 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321874 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571875
[email protected]2431756e2010-09-29 20:26:131876 std::vector<TestSocketRequest*> request_order;
1877 size_t completion_count; // unused
1878 TestSocketRequest req1(&request_order, &completion_count);
1879 int rv = req1.handle()->Init("a",
1880 params_,
1881 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521882 req1.callback(),
[email protected]2431756e2010-09-29 20:26:131883 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211884 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571885 EXPECT_EQ(ERR_IO_PENDING, rv);
1886
[email protected]2431756e2010-09-29 20:26:131887 TestSocketRequest req2(&request_order, &completion_count);
1888 rv = req2.handle()->Init("a",
1889 params_,
1890 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521891 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131892 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211893 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571894 EXPECT_EQ(ERR_IO_PENDING, rv);
1895
1896 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321897 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571898
[email protected]2431756e2010-09-29 20:26:131899 TestSocketRequest req3(&request_order, &completion_count);
1900 rv = req3.handle()->Init("a",
1901 params_,
1902 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521903 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131904 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211905 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571906 EXPECT_EQ(ERR_IO_PENDING, rv);
1907
1908 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1909 EXPECT_EQ(OK, req2.WaitForResult());
1910 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1911
[email protected]2431756e2010-09-29 20:26:131912 ASSERT_EQ(3U, request_order.size());
1913 EXPECT_EQ(&req1, request_order[0]);
1914 EXPECT_EQ(&req2, request_order[1]);
1915 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571916}
1917
[email protected]e6ec67b2010-06-16 00:12:461918TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531919 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571920 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321921 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571922
[email protected]2431756e2010-09-29 20:26:131923 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521924 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131925 int rv = handle.Init("a",
1926 params_,
1927 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521928 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131929 pool_.get(),
1930 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571931 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131932 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571933
[email protected]b4c62eb2012-11-14 18:36:511934 MessageLoop::current()->RunUntilIdle();
[email protected]5fc08e32009-07-15 17:09:571935
[email protected]2431756e2010-09-29 20:26:131936 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521937 TestCompletionCallback callback2;
1938 rv = handle2.Init("a", params_, kDefaultPriority, callback2.callback(),
1939 pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571940 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131941 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1942 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571943}
1944
[email protected]e772db3f2010-07-12 18:11:131945TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1946 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1947 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1948
[email protected]2431756e2010-09-29 20:26:131949 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521950 TestCompletionCallback callback;
1951 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
1952 handle.Init("a", params_, kDefaultPriority, callback.callback(),
1953 pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:131954 EXPECT_TRUE(handle.is_initialized());
1955 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131956}
1957
1958TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1959 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1960
1961 connect_job_factory_->set_job_type(
1962 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131963 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521964 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131965 EXPECT_EQ(ERR_IO_PENDING,
1966 handle.Init("a",
1967 params_,
1968 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521969 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131970 pool_.get(),
1971 BoundNetLog()));
1972 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1973 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1974 EXPECT_TRUE(handle.is_initialized());
1975 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131976}
1977
[email protected]e60e47a2010-07-14 03:37:181978TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1979 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1980 connect_job_factory_->set_job_type(
1981 TestConnectJob::kMockAdditionalErrorStateJob);
1982
[email protected]2431756e2010-09-29 20:26:131983 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521984 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131985 EXPECT_EQ(ERR_CONNECTION_FAILED,
1986 handle.Init("a",
1987 params_,
1988 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521989 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131990 pool_.get(),
1991 BoundNetLog()));
1992 EXPECT_FALSE(handle.is_initialized());
1993 EXPECT_FALSE(handle.socket());
1994 EXPECT_TRUE(handle.is_ssl_error());
1995 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181996}
1997
1998TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1999 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2000
2001 connect_job_factory_->set_job_type(
2002 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132003 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522004 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132005 EXPECT_EQ(ERR_IO_PENDING,
2006 handle.Init("a",
2007 params_,
2008 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522009 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132010 pool_.get(),
2011 BoundNetLog()));
2012 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2013 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
2014 EXPECT_FALSE(handle.is_initialized());
2015 EXPECT_FALSE(handle.socket());
2016 EXPECT_TRUE(handle.is_ssl_error());
2017 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182018}
2019
[email protected]e7b1c6d2c2012-05-05 00:54:032020// Make sure we can reuse sockets when the cleanup timer is disabled.
2021TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerReuse) {
[email protected]64770b7d2011-11-16 04:30:412022 // Disable cleanup timer.
2023 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2024
2025 CreatePoolWithIdleTimeouts(
2026 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032027 base::TimeDelta(), // Time out unused sockets immediately.
2028 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2029
2030 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2031
2032 ClientSocketHandle handle;
2033 TestCompletionCallback callback;
2034 int rv = handle.Init("a",
2035 params_,
2036 LOWEST,
2037 callback.callback(),
2038 pool_.get(),
2039 BoundNetLog());
2040 ASSERT_EQ(ERR_IO_PENDING, rv);
2041 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2042 ASSERT_EQ(OK, callback.WaitForResult());
2043
2044 // Use and release the socket.
2045 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]034df0f32013-01-07 23:17:482046 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032047 handle.Reset();
2048
2049 // Should now have one idle socket.
2050 ASSERT_EQ(1, pool_->IdleSocketCount());
2051
2052 // Request a new socket. This should reuse the old socket and complete
2053 // synchronously.
[email protected]333bdf62012-06-08 22:57:292054 CapturingBoundNetLog log;
[email protected]e7b1c6d2c2012-05-05 00:54:032055 rv = handle.Init("a",
2056 params_,
2057 LOWEST,
2058 CompletionCallback(),
2059 pool_.get(),
2060 log.bound());
2061 ASSERT_EQ(OK, rv);
2062 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482063 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032064
2065 ASSERT_TRUE(pool_->HasGroup("a"));
2066 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2067 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2068
[email protected]333bdf62012-06-08 22:57:292069 CapturingNetLog::CapturedEntryList entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032070 log.GetEntries(&entries);
2071 EXPECT_TRUE(LogContainsEntryWithType(
2072 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2073}
2074
2075// Make sure we cleanup old unused sockets when the cleanup timer is disabled.
2076TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerNoReuse) {
2077 // Disable cleanup timer.
2078 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2079
2080 CreatePoolWithIdleTimeouts(
2081 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2082 base::TimeDelta(), // Time out unused sockets immediately
2083 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412084
2085 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2086
2087 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2088
2089 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522090 TestCompletionCallback callback;
[email protected]64770b7d2011-11-16 04:30:412091 int rv = handle.Init("a",
2092 params_,
2093 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522094 callback.callback(),
[email protected]64770b7d2011-11-16 04:30:412095 pool_.get(),
2096 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032097 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412098 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2099
2100 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522101 TestCompletionCallback callback2;
[email protected]64770b7d2011-11-16 04:30:412102 rv = handle2.Init("a",
2103 params_,
2104 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522105 callback2.callback(),
[email protected]64770b7d2011-11-16 04:30:412106 pool_.get(),
2107 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032108 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412109 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2110
2111 // Cancel one of the requests. Wait for the other, which will get the first
2112 // job. Release the socket. Run the loop again to make sure the second
2113 // socket is sitting idle and the first one is released (since ReleaseSocket()
2114 // just posts a DoReleaseSocket() task).
2115
2116 handle.Reset();
[email protected]e7b1c6d2c2012-05-05 00:54:032117 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412118 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552119 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412120 handle2.Reset();
2121
[email protected]e7b1c6d2c2012-05-05 00:54:032122 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2123 // actually become pending until 2ms after they have been created. In order
2124 // to flush all tasks, we need to wait so that we know there are no
2125 // soon-to-be-pending tasks waiting.
2126 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]b4c62eb2012-11-14 18:36:512127 MessageLoop::current()->RunUntilIdle();
[email protected]64770b7d2011-11-16 04:30:412128
[email protected]e7b1c6d2c2012-05-05 00:54:032129 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412130 ASSERT_EQ(2, pool_->IdleSocketCount());
2131
2132 // Request a new socket. This should cleanup the unused and timed out ones.
2133 // A new socket will be created rather than reusing the idle one.
[email protected]333bdf62012-06-08 22:57:292134 CapturingBoundNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522135 TestCompletionCallback callback3;
[email protected]64770b7d2011-11-16 04:30:412136 rv = handle.Init("a",
2137 params_,
2138 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522139 callback3.callback(),
[email protected]64770b7d2011-11-16 04:30:412140 pool_.get(),
2141 log.bound());
[email protected]e7b1c6d2c2012-05-05 00:54:032142 ASSERT_EQ(ERR_IO_PENDING, rv);
2143 ASSERT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412144 EXPECT_FALSE(handle.is_reused());
2145
[email protected]e7b1c6d2c2012-05-05 00:54:032146 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412147 ASSERT_TRUE(pool_->HasGroup("a"));
2148 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2149 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2150
[email protected]333bdf62012-06-08 22:57:292151 CapturingNetLog::CapturedEntryList entries;
[email protected]64770b7d2011-11-16 04:30:412152 log.GetEntries(&entries);
2153 EXPECT_FALSE(LogContainsEntryWithType(
2154 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2155}
2156
[email protected]4d3b05d2010-01-27 21:27:292157TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162158 CreatePoolWithIdleTimeouts(
2159 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2160 base::TimeDelta(), // Time out unused sockets immediately.
2161 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2162
2163 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2164
2165 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2166
[email protected]2431756e2010-09-29 20:26:132167 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522168 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132169 int rv = handle.Init("a",
2170 params_,
2171 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522172 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132173 pool_.get(),
2174 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162175 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132176 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162177
[email protected]2431756e2010-09-29 20:26:132178 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522179 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132180 rv = handle2.Init("a",
2181 params_,
2182 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522183 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132184 pool_.get(),
2185 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162186 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132187 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162188
2189 // Cancel one of the requests. Wait for the other, which will get the first
2190 // job. Release the socket. Run the loop again to make sure the second
2191 // socket is sitting idle and the first one is released (since ReleaseSocket()
2192 // just posts a DoReleaseSocket() task).
2193
[email protected]2431756e2010-09-29 20:26:132194 handle.Reset();
2195 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012196 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552197 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]2431756e2010-09-29 20:26:132198 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472199
2200 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2201 // actually become pending until 2ms after they have been created. In order
2202 // to flush all tasks, we need to wait so that we know there are no
2203 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:002204 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]b4c62eb2012-11-14 18:36:512205 MessageLoop::current()->RunUntilIdle();
[email protected]9bf28db2009-08-29 01:35:162206
2207 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042208
[email protected]9bf28db2009-08-29 01:35:162209 // Invoke the idle socket cleanup check. Only one socket should be left, the
2210 // used socket. Request it to make sure that it's used.
2211
2212 pool_->CleanupTimedOutIdleSockets();
[email protected]333bdf62012-06-08 22:57:292213 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:132214 rv = handle.Init("a",
2215 params_,
2216 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522217 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132218 pool_.get(),
2219 log.bound());
[email protected]9bf28db2009-08-29 01:35:162220 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132221 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402222
[email protected]333bdf62012-06-08 22:57:292223 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402224 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152225 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402226 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162227}
2228
[email protected]2041cf342010-02-19 03:15:592229// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162230// because of multiple releasing disconnected sockets.
2231TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2232 CreatePoolWithIdleTimeouts(
2233 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2234 base::TimeDelta(), // Time out unused sockets immediately.
2235 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2236
2237 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2238
2239 // Startup 4 connect jobs. Two of them will be pending.
2240
[email protected]2431756e2010-09-29 20:26:132241 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522242 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132243 int rv = handle.Init("a",
2244 params_,
2245 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522246 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132247 pool_.get(),
2248 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162249 EXPECT_EQ(OK, rv);
2250
[email protected]2431756e2010-09-29 20:26:132251 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522252 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132253 rv = handle2.Init("a",
2254 params_,
2255 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522256 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132257 pool_.get(),
2258 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162259 EXPECT_EQ(OK, rv);
2260
[email protected]2431756e2010-09-29 20:26:132261 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522262 TestCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132263 rv = handle3.Init("a",
2264 params_,
2265 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522266 callback3.callback(),
[email protected]2431756e2010-09-29 20:26:132267 pool_.get(),
2268 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162269 EXPECT_EQ(ERR_IO_PENDING, rv);
2270
[email protected]2431756e2010-09-29 20:26:132271 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522272 TestCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132273 rv = handle4.Init("a",
2274 params_,
2275 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522276 callback4.callback(),
[email protected]2431756e2010-09-29 20:26:132277 pool_.get(),
2278 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162279 EXPECT_EQ(ERR_IO_PENDING, rv);
2280
2281 // Release two disconnected sockets.
2282
[email protected]2431756e2010-09-29 20:26:132283 handle.socket()->Disconnect();
2284 handle.Reset();
2285 handle2.socket()->Disconnect();
2286 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162287
[email protected]2431756e2010-09-29 20:26:132288 EXPECT_EQ(OK, callback3.WaitForResult());
2289 EXPECT_FALSE(handle3.is_reused());
2290 EXPECT_EQ(OK, callback4.WaitForResult());
2291 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162292}
2293
[email protected]d7027bb2010-05-10 18:58:542294// Regression test for http://crbug.com/42267.
2295// When DoReleaseSocket() is processed for one socket, it is blocked because the
2296// other stalled groups all have releasing sockets, so no progress can be made.
2297TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2298 CreatePoolWithIdleTimeouts(
2299 4 /* socket limit */, 4 /* socket limit per group */,
2300 base::TimeDelta(), // Time out unused sockets immediately.
2301 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2302
2303 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2304
2305 // Max out the socket limit with 2 per group.
2306
[email protected]2431756e2010-09-29 20:26:132307 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522308 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132309 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522310 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542311
2312 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132313 EXPECT_EQ(OK, handle_a[i].Init("a",
2314 params_,
2315 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522316 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132317 pool_.get(),
2318 BoundNetLog()));
2319 EXPECT_EQ(OK, handle_b[i].Init("b",
2320 params_,
2321 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522322 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132323 pool_.get(),
2324 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542325 }
[email protected]b89f7e42010-05-20 20:37:002326
[email protected]d7027bb2010-05-10 18:58:542327 // Make 4 pending requests, 2 per group.
2328
2329 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132330 EXPECT_EQ(ERR_IO_PENDING,
2331 handle_a[i].Init("a",
2332 params_,
2333 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522334 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132335 pool_.get(),
2336 BoundNetLog()));
2337 EXPECT_EQ(ERR_IO_PENDING,
2338 handle_b[i].Init("b",
2339 params_,
2340 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522341 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132342 pool_.get(),
2343 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542344 }
2345
2346 // Release b's socket first. The order is important, because in
2347 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2348 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2349 // first, which has a releasing socket, so it refuses to start up another
2350 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132351 handle_b[0].socket()->Disconnect();
2352 handle_b[0].Reset();
2353 handle_a[0].socket()->Disconnect();
2354 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542355
2356 // Used to get stuck here.
[email protected]b4c62eb2012-11-14 18:36:512357 MessageLoop::current()->RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542358
[email protected]2431756e2010-09-29 20:26:132359 handle_b[1].socket()->Disconnect();
2360 handle_b[1].Reset();
2361 handle_a[1].socket()->Disconnect();
2362 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542363
2364 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132365 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2366 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542367 }
2368}
2369
[email protected]fd4fe0b2010-02-08 23:02:152370TEST_F(ClientSocketPoolBaseTest,
2371 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2372 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2373
2374 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2375
2376 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2377 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2378 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2379 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2380
[email protected]2431756e2010-09-29 20:26:132381 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2382 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2383 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152384
2385 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132386 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2387 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152388
[email protected]2431756e2010-09-29 20:26:132389 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2390 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2391 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152392
2393 EXPECT_EQ(1, GetOrderOfRequest(1));
2394 EXPECT_EQ(2, GetOrderOfRequest(2));
2395 EXPECT_EQ(3, GetOrderOfRequest(3));
2396 EXPECT_EQ(4, GetOrderOfRequest(4));
2397
2398 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132399 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152400}
2401
[email protected]6ecf2b92011-12-15 01:14:522402class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042403 public:
[email protected]2431756e2010-09-29 20:26:132404 TestReleasingSocketRequest(TestClientSocketPool* pool,
2405 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182406 bool reset_releasing_handle)
2407 : pool_(pool),
2408 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522409 reset_releasing_handle_(reset_releasing_handle),
[email protected]aa249b52013-04-30 01:04:322410 callback_(base::Bind(&TestReleasingSocketRequest::OnComplete,
2411 base::Unretained(this))) {
[email protected]6ecf2b92011-12-15 01:14:522412 }
2413
2414 virtual ~TestReleasingSocketRequest() {}
[email protected]4f1e4982010-03-02 18:31:042415
2416 ClientSocketHandle* handle() { return &handle_; }
2417
[email protected]6ecf2b92011-12-15 01:14:522418 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042419
2420 private:
[email protected]6ecf2b92011-12-15 01:14:522421 void OnComplete(int result) {
2422 SetResult(result);
2423 if (reset_releasing_handle_)
2424 handle_.Reset();
2425
2426 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
2427 EXPECT_EQ(expected_result_,
2428 handle2_.Init("a", con_params, kDefaultPriority,
2429 callback2_.callback(), pool_, BoundNetLog()));
2430 }
2431
[email protected]2431756e2010-09-29 20:26:132432 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182433 int expected_result_;
2434 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042435 ClientSocketHandle handle_;
2436 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522437 CompletionCallback callback_;
2438 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042439};
2440
[email protected]e60e47a2010-07-14 03:37:182441
2442TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2443 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2444
2445 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2446 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2447 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2448
[email protected]2431756e2010-09-29 20:26:132449 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182450 client_socket_factory_.allocation_count());
2451
2452 connect_job_factory_->set_job_type(
2453 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2454 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132455 EXPECT_EQ(ERR_IO_PENDING,
[email protected]6ecf2b92011-12-15 01:14:522456 req.handle()->Init("a", params_, kDefaultPriority, req.callback(),
2457 pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182458 // The next job should complete synchronously
2459 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2460
2461 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2462 EXPECT_FALSE(req.handle()->is_initialized());
2463 EXPECT_FALSE(req.handle()->socket());
2464 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432465 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182466}
2467
[email protected]b6501d3d2010-06-03 23:53:342468// http://crbug.com/44724 regression test.
2469// We start releasing the pool when we flush on network change. When that
2470// happens, the only active references are in the ClientSocketHandles. When a
2471// ConnectJob completes and calls back into the last ClientSocketHandle, that
2472// callback can release the last reference and delete the pool. After the
2473// callback finishes, we go back to the stack frame within the now-deleted pool.
2474// Executing any code that refers to members of the now-deleted pool can cause
2475// crashes.
2476TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2477 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2478 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2479
2480 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522481 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132482 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2483 params_,
2484 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522485 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132486 pool_.get(),
2487 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342488
[email protected]7af985a2012-12-14 22:40:422489 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342490
2491 // We'll call back into this now.
2492 callback.WaitForResult();
2493}
2494
[email protected]a7e38572010-06-07 18:22:242495TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2496 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2497 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2498
2499 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522500 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132501 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2502 params_,
2503 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522504 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132505 pool_.get(),
2506 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242507 EXPECT_EQ(OK, callback.WaitForResult());
2508 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2509
[email protected]7af985a2012-12-14 22:40:422510 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242511
2512 handle.Reset();
[email protected]b4c62eb2012-11-14 18:36:512513 MessageLoop::current()->RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242514
[email protected]2431756e2010-09-29 20:26:132515 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2516 params_,
2517 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522518 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132519 pool_.get(),
2520 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242521 EXPECT_EQ(OK, callback.WaitForResult());
2522 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2523}
2524
[email protected]6ecf2b92011-12-15 01:14:522525class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142526 public:
2527 ConnectWithinCallback(
2528 const std::string& group_name,
2529 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132530 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522531 : group_name_(group_name),
2532 params_(params),
2533 pool_(pool),
[email protected]aa249b52013-04-30 01:04:322534 callback_(base::Bind(&ConnectWithinCallback::OnComplete,
2535 base::Unretained(this))) {
[email protected]06f92462010-08-31 19:24:142536 }
2537
[email protected]6ecf2b92011-12-15 01:14:522538 virtual ~ConnectWithinCallback() {}
[email protected]06f92462010-08-31 19:24:142539
2540 int WaitForNestedResult() {
2541 return nested_callback_.WaitForResult();
2542 }
2543
[email protected]6ecf2b92011-12-15 01:14:522544 const CompletionCallback& callback() const { return callback_; }
2545
[email protected]06f92462010-08-31 19:24:142546 private:
[email protected]6ecf2b92011-12-15 01:14:522547 void OnComplete(int result) {
2548 SetResult(result);
2549 EXPECT_EQ(ERR_IO_PENDING,
2550 handle_.Init(group_name_,
2551 params_,
2552 kDefaultPriority,
2553 nested_callback_.callback(),
2554 pool_,
2555 BoundNetLog()));
2556 }
2557
[email protected]06f92462010-08-31 19:24:142558 const std::string group_name_;
2559 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132560 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142561 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522562 CompletionCallback callback_;
2563 TestCompletionCallback nested_callback_;
2564
2565 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142566};
2567
2568TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2569 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2570
2571 // First job will be waiting until it gets aborted.
2572 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2573
2574 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132575 ConnectWithinCallback callback("a", params_, pool_.get());
2576 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2577 params_,
2578 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522579 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132580 pool_.get(),
2581 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142582
2583 // Second job will be started during the first callback, and will
2584 // asynchronously complete with OK.
2585 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422586 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2587 EXPECT_EQ(ERR_NETWORK_CHANGED, callback.WaitForResult());
[email protected]06f92462010-08-31 19:24:142588 EXPECT_EQ(OK, callback.WaitForNestedResult());
2589}
2590
[email protected]25eea382010-07-10 23:55:262591// Cancel a pending socket request while we're at max sockets,
2592// and verify that the backup socket firing doesn't cause a crash.
2593TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2594 // Max 4 sockets globally, max 4 sockets per group.
2595 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222596 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262597
[email protected]4baaf9d2010-08-31 15:15:442598 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2599 // timer.
[email protected]25eea382010-07-10 23:55:262600 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2601 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522602 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132603 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2604 params_,
2605 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522606 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132607 pool_.get(),
2608 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262609
2610 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2611 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2612 ClientSocketHandle handles[kDefaultMaxSockets];
2613 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522614 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132615 EXPECT_EQ(OK, handles[i].Init("bar",
2616 params_,
2617 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522618 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132619 pool_.get(),
2620 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262621 }
2622
[email protected]b4c62eb2012-11-14 18:36:512623 MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262624
2625 // Cancel the pending request.
2626 handle.Reset();
2627
2628 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002629 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2630 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262631
[email protected]b4c62eb2012-11-14 18:36:512632 MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262633 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2634}
2635
[email protected]3f00be82010-09-27 19:50:022636TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442637 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2638 pool_->EnableConnectBackupJobs();
2639
2640 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2641 // timer.
2642 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2643 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522644 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132645 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2646 params_,
2647 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522648 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132649 pool_.get(),
2650 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442651 ASSERT_TRUE(pool_->HasGroup("bar"));
2652 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102653 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442654
2655 // Cancel the socket request. This should cancel the backup timer. Wait for
2656 // the backup time to see if it indeed got canceled.
2657 handle.Reset();
2658 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002659 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2660 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]b4c62eb2012-11-14 18:36:512661 MessageLoop::current()->RunUntilIdle();
[email protected]4baaf9d2010-08-31 15:15:442662 ASSERT_TRUE(pool_->HasGroup("bar"));
2663 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2664}
2665
[email protected]3f00be82010-09-27 19:50:022666TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2667 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2668 pool_->EnableConnectBackupJobs();
2669
2670 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2671 // timer.
2672 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2673 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522674 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132675 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2676 params_,
2677 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522678 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132679 pool_.get(),
2680 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022681 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2682 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522683 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132684 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2685 params_,
2686 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522687 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132688 pool_.get(),
2689 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022690 ASSERT_TRUE(pool_->HasGroup("bar"));
2691 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2692
2693 // Cancel request 1 and then complete request 2. With the requests finished,
2694 // the backup timer should be cancelled.
2695 handle.Reset();
2696 EXPECT_EQ(OK, callback2.WaitForResult());
2697 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002698 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2699 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]b4c62eb2012-11-14 18:36:512700 MessageLoop::current()->RunUntilIdle();
[email protected]3f00be82010-09-27 19:50:022701}
2702
[email protected]eb5a99382010-07-11 03:18:262703// Test delayed socket binding for the case where we have two connects,
2704// and while one is waiting on a connect, the other frees up.
2705// The socket waiting on a connect should switch immediately to the freed
2706// up socket.
2707TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2708 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2709 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2710
2711 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522712 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132713 EXPECT_EQ(ERR_IO_PENDING,
2714 handle1.Init("a",
2715 params_,
2716 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522717 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132718 pool_.get(),
2719 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262720 EXPECT_EQ(OK, callback.WaitForResult());
2721
2722 // No idle sockets, no pending jobs.
2723 EXPECT_EQ(0, pool_->IdleSocketCount());
2724 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2725
2726 // Create a second socket to the same host, but this one will wait.
2727 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2728 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132729 EXPECT_EQ(ERR_IO_PENDING,
2730 handle2.Init("a",
2731 params_,
2732 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522733 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132734 pool_.get(),
2735 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262736 // No idle sockets, and one connecting job.
2737 EXPECT_EQ(0, pool_->IdleSocketCount());
2738 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2739
2740 // Return the first handle to the pool. This will initiate the delayed
2741 // binding.
2742 handle1.Reset();
2743
[email protected]b4c62eb2012-11-14 18:36:512744 MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262745
2746 // Still no idle sockets, still one pending connect job.
2747 EXPECT_EQ(0, pool_->IdleSocketCount());
2748 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2749
2750 // The second socket connected, even though it was a Waiting Job.
2751 EXPECT_EQ(OK, callback.WaitForResult());
2752
2753 // And we can see there is still one job waiting.
2754 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2755
2756 // Finally, signal the waiting Connect.
2757 client_socket_factory_.SignalJobs();
2758 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2759
[email protected]b4c62eb2012-11-14 18:36:512760 MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262761}
2762
2763// Test delayed socket binding when a group is at capacity and one
2764// of the group's sockets frees up.
2765TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2766 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2767 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2768
2769 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522770 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132771 EXPECT_EQ(ERR_IO_PENDING,
2772 handle1.Init("a",
2773 params_,
2774 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522775 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132776 pool_.get(),
2777 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262778 EXPECT_EQ(OK, callback.WaitForResult());
2779
2780 // No idle sockets, no pending jobs.
2781 EXPECT_EQ(0, pool_->IdleSocketCount());
2782 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2783
2784 // Create a second socket to the same host, but this one will wait.
2785 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2786 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132787 EXPECT_EQ(ERR_IO_PENDING,
2788 handle2.Init("a",
2789 params_,
2790 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522791 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132792 pool_.get(),
2793 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262794 // No idle sockets, and one connecting job.
2795 EXPECT_EQ(0, pool_->IdleSocketCount());
2796 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2797
2798 // Return the first handle to the pool. This will initiate the delayed
2799 // binding.
2800 handle1.Reset();
2801
[email protected]b4c62eb2012-11-14 18:36:512802 MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262803
2804 // Still no idle sockets, still one pending connect job.
2805 EXPECT_EQ(0, pool_->IdleSocketCount());
2806 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2807
2808 // The second socket connected, even though it was a Waiting Job.
2809 EXPECT_EQ(OK, callback.WaitForResult());
2810
2811 // And we can see there is still one job waiting.
2812 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2813
2814 // Finally, signal the waiting Connect.
2815 client_socket_factory_.SignalJobs();
2816 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2817
[email protected]b4c62eb2012-11-14 18:36:512818 MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262819}
2820
2821// Test out the case where we have one socket connected, one
2822// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512823// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262824// should complete, by taking the first socket's idle socket.
2825TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2826 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2827 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2828
2829 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522830 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132831 EXPECT_EQ(ERR_IO_PENDING,
2832 handle1.Init("a",
2833 params_,
2834 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522835 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132836 pool_.get(),
2837 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262838 EXPECT_EQ(OK, callback.WaitForResult());
2839
2840 // No idle sockets, no pending jobs.
2841 EXPECT_EQ(0, pool_->IdleSocketCount());
2842 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2843
2844 // Create a second socket to the same host, but this one will wait.
2845 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2846 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132847 EXPECT_EQ(ERR_IO_PENDING,
2848 handle2.Init("a",
2849 params_,
2850 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522851 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132852 pool_.get(),
2853 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262854 // No idle sockets, and one connecting job.
2855 EXPECT_EQ(0, pool_->IdleSocketCount());
2856 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2857
2858 // Return the first handle to the pool. This will initiate the delayed
2859 // binding.
2860 handle1.Reset();
2861
[email protected]b4c62eb2012-11-14 18:36:512862 MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262863
2864 // Still no idle sockets, still one pending connect job.
2865 EXPECT_EQ(0, pool_->IdleSocketCount());
2866 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2867
2868 // The second socket connected, even though it was a Waiting Job.
2869 EXPECT_EQ(OK, callback.WaitForResult());
2870
2871 // And we can see there is still one job waiting.
2872 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2873
2874 // Finally, signal the waiting Connect.
2875 client_socket_factory_.SignalJobs();
2876 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2877
[email protected]b4c62eb2012-11-14 18:36:512878 MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262879}
2880
[email protected]2abfe90a2010-08-25 17:49:512881// Cover the case where on an available socket slot, we have one pending
2882// request that completes synchronously, thereby making the Group empty.
2883TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2884 const int kUnlimitedSockets = 100;
2885 const int kOneSocketPerGroup = 1;
2886 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2887
2888 // Make the first request asynchronous fail.
2889 // This will free up a socket slot later.
2890 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2891
2892 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522893 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132894 EXPECT_EQ(ERR_IO_PENDING,
2895 handle1.Init("a",
2896 params_,
2897 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522898 callback1.callback(),
[email protected]2431756e2010-09-29 20:26:132899 pool_.get(),
2900 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512901 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2902
2903 // Make the second request synchronously fail. This should make the Group
2904 // empty.
2905 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2906 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522907 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:512908 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2909 // when created.
[email protected]2431756e2010-09-29 20:26:132910 EXPECT_EQ(ERR_IO_PENDING,
2911 handle2.Init("a",
2912 params_,
2913 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522914 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132915 pool_.get(),
2916 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512917
2918 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2919
2920 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2921 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2922 EXPECT_FALSE(pool_->HasGroup("a"));
2923}
2924
[email protected]e1b54dc2010-10-06 21:27:222925TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2926 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2927
2928 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2929
2930 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522931 TestCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:222932 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2933 params_,
2934 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522935 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:222936 pool_.get(),
2937 BoundNetLog()));
2938
2939 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522940 TestCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:222941 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2942 params_,
2943 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522944 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:222945 pool_.get(),
2946 BoundNetLog()));
2947 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522948 TestCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:222949 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2950 params_,
2951 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522952 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:222953 pool_.get(),
2954 BoundNetLog()));
2955
2956 EXPECT_EQ(OK, callback1.WaitForResult());
2957 EXPECT_EQ(OK, callback2.WaitForResult());
2958 EXPECT_EQ(OK, callback3.WaitForResult());
2959
2960 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552961 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
2962 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:222963
2964 handle1.Reset();
2965 handle2.Reset();
2966 handle3.Reset();
2967
2968 EXPECT_EQ(OK, handle1.Init("a",
2969 params_,
2970 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522971 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:222972 pool_.get(),
2973 BoundNetLog()));
2974 EXPECT_EQ(OK, handle2.Init("a",
2975 params_,
2976 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522977 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:222978 pool_.get(),
2979 BoundNetLog()));
2980 EXPECT_EQ(OK, handle3.Init("a",
2981 params_,
2982 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522983 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:222984 pool_.get(),
2985 BoundNetLog()));
2986
2987 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2988 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2989 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2990}
2991
[email protected]2c2bef152010-10-13 00:55:032992TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2993 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2994 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2995
2996 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2997
2998 ASSERT_TRUE(pool_->HasGroup("a"));
2999 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103000 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033001 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3002
3003 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523004 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033005 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3006 params_,
3007 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523008 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033009 pool_.get(),
3010 BoundNetLog()));
3011
3012 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523013 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033014 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3015 params_,
3016 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523017 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033018 pool_.get(),
3019 BoundNetLog()));
3020
3021 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103022 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033023 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3024
3025 EXPECT_EQ(OK, callback1.WaitForResult());
3026 EXPECT_EQ(OK, callback2.WaitForResult());
3027 handle1.Reset();
3028 handle2.Reset();
3029
3030 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103031 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033032 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3033}
3034
3035TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3036 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3037 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3038
3039 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523040 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033041 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3042 params_,
3043 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523044 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033045 pool_.get(),
3046 BoundNetLog()));
3047
3048 ASSERT_TRUE(pool_->HasGroup("a"));
3049 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103050 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033051 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3052
3053 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3054
3055 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103056 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033057 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3058
3059 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523060 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033061 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3062 params_,
3063 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523064 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033065 pool_.get(),
3066 BoundNetLog()));
3067
3068 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103069 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033070 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3071
3072 EXPECT_EQ(OK, callback1.WaitForResult());
3073 EXPECT_EQ(OK, callback2.WaitForResult());
3074 handle1.Reset();
3075 handle2.Reset();
3076
3077 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103078 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033079 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3080}
3081
3082TEST_F(ClientSocketPoolBaseTest,
3083 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3084 CreatePool(4, 4);
3085 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3086
3087 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523088 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033089 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3090 params_,
3091 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523092 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033093 pool_.get(),
3094 BoundNetLog()));
3095
3096 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523097 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033098 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3099 params_,
3100 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523101 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033102 pool_.get(),
3103 BoundNetLog()));
3104
3105 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523106 TestCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:033107 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3108 params_,
3109 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523110 callback3.callback(),
[email protected]2c2bef152010-10-13 00:55:033111 pool_.get(),
3112 BoundNetLog()));
3113
3114 ASSERT_TRUE(pool_->HasGroup("a"));
3115 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103116 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033117 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3118
3119 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3120
3121 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103122 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033123 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3124
3125 EXPECT_EQ(OK, callback1.WaitForResult());
3126 EXPECT_EQ(OK, callback2.WaitForResult());
3127 EXPECT_EQ(OK, callback3.WaitForResult());
3128 handle1.Reset();
3129 handle2.Reset();
3130 handle3.Reset();
3131
3132 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103133 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033134 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3135}
3136
3137TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3138 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3139 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3140
3141 ASSERT_FALSE(pool_->HasGroup("a"));
3142
3143 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3144 BoundNetLog());
3145
3146 ASSERT_TRUE(pool_->HasGroup("a"));
3147 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103148 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033149
3150 ASSERT_FALSE(pool_->HasGroup("b"));
3151
3152 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3153 BoundNetLog());
3154
3155 ASSERT_FALSE(pool_->HasGroup("b"));
3156}
3157
3158TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3159 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3160 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3161
3162 ASSERT_FALSE(pool_->HasGroup("a"));
3163
3164 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3165 BoundNetLog());
3166
3167 ASSERT_TRUE(pool_->HasGroup("a"));
3168 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103169 EXPECT_EQ(kDefaultMaxSockets - 1,
3170 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483171 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033172
3173 ASSERT_FALSE(pool_->HasGroup("b"));
3174
3175 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3176 BoundNetLog());
3177
3178 ASSERT_TRUE(pool_->HasGroup("b"));
3179 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483180 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033181}
3182
3183TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3184 CreatePool(4, 4);
3185 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3186
3187 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523188 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033189 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3190 params_,
3191 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523192 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033193 pool_.get(),
3194 BoundNetLog()));
3195 ASSERT_EQ(OK, callback1.WaitForResult());
3196 handle1.Reset();
3197
3198 ASSERT_TRUE(pool_->HasGroup("a"));
3199 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103200 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033201 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3202
3203 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3204
3205 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103206 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033207 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3208}
3209
3210TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3211 CreatePool(4, 4);
3212 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3213
3214 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523215 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033216 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3217 params_,
3218 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523219 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033220 pool_.get(),
3221 BoundNetLog()));
3222 ASSERT_EQ(OK, callback1.WaitForResult());
3223
3224 ASSERT_TRUE(pool_->HasGroup("a"));
3225 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103226 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033227 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3228 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3229
3230 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3231
3232 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103233 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033234 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3235 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3236}
3237
3238TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3239 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3240 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3241
3242 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3243 BoundNetLog());
3244
3245 ASSERT_TRUE(pool_->HasGroup("a"));
3246 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103247 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033248 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3249
3250 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3251 BoundNetLog());
3252
3253 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103254 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033255 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3256}
3257
[email protected]3c819f522010-12-02 02:03:123258TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3259 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3260 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3261
3262 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3263 BoundNetLog());
3264
3265 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523266
3267 connect_job_factory_->set_job_type(
3268 TestConnectJob::kMockAdditionalErrorStateJob);
3269 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3270 BoundNetLog());
3271
3272 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123273}
3274
[email protected]8159a1c2012-06-07 00:00:103275TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033276 CreatePool(4, 4);
3277 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3278
3279 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3280
3281 ASSERT_TRUE(pool_->HasGroup("a"));
3282 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103283 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033284 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3285
3286 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3287 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103288 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033289 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3290
3291 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523292 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033293 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3294 params_,
3295 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523296 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033297 pool_.get(),
3298 BoundNetLog()));
3299 ASSERT_EQ(OK, callback1.WaitForResult());
3300
3301 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523302 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033303 int rv = handle2.Init("a",
3304 params_,
3305 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523306 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033307 pool_.get(),
3308 BoundNetLog());
3309 if (rv != OK) {
3310 EXPECT_EQ(ERR_IO_PENDING, rv);
3311 EXPECT_EQ(OK, callback2.WaitForResult());
3312 }
3313
[email protected]8159a1c2012-06-07 00:00:103314 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3315 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3316 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3317 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3318
[email protected]2c2bef152010-10-13 00:55:033319 handle1.Reset();
3320 handle2.Reset();
3321
[email protected]8159a1c2012-06-07 00:00:103322 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3323 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033324 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3325
3326 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3327 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103328 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033329 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3330}
3331
3332TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3333 CreatePool(4, 4);
3334 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3335
3336 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3337
3338 ASSERT_TRUE(pool_->HasGroup("a"));
3339 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103340 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033341 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3342
3343 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3344 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103345 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033346 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3347
3348 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3349 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103350 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033351 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3352
3353 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3354 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103355 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033356 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3357}
3358
3359TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3360 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3361 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3362
3363 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3364
3365 ASSERT_TRUE(pool_->HasGroup("a"));
3366 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103367 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033368 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3369
3370 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523371 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033372 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3373 params_,
3374 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523375 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033376 pool_.get(),
3377 BoundNetLog()));
3378
3379 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103380 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033381 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3382
3383 ASSERT_EQ(OK, callback1.WaitForResult());
3384
[email protected]034df0f32013-01-07 23:17:483385 // Make sure if a preconneced socket is not fully connected when a request
3386 // starts, it has a connect start time.
3387 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033388 handle1.Reset();
3389
3390 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3391}
3392
[email protected]034df0f32013-01-07 23:17:483393// Checks that fully connected preconnect jobs have no connect times, and are
3394// marked as reused.
3395TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3396 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3397 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3398 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3399
3400 ASSERT_TRUE(pool_->HasGroup("a"));
3401 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3402 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3403 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3404
3405 ClientSocketHandle handle;
3406 TestCompletionCallback callback;
3407 EXPECT_EQ(OK, handle.Init("a",
3408 params_,
3409 kDefaultPriority,
3410 callback.callback(),
3411 pool_.get(),
3412 BoundNetLog()));
3413
3414 // Make sure the idle socket was used.
3415 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3416
3417 TestLoadTimingInfoConnectedReused(handle);
3418 handle.Reset();
3419 TestLoadTimingInfoNotConnected(handle);
3420}
3421
[email protected]dcbe168a2010-12-02 03:14:463422// http://crbug.com/64940 regression test.
3423TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3424 const int kMaxTotalSockets = 3;
3425 const int kMaxSocketsPerGroup = 2;
3426 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3427 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3428
3429 // Note that group name ordering matters here. "a" comes before "b", so
3430 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3431
3432 // Set up one idle socket in "a".
3433 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523434 TestCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463435 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3436 params_,
3437 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523438 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463439 pool_.get(),
3440 BoundNetLog()));
3441
3442 ASSERT_EQ(OK, callback1.WaitForResult());
3443 handle1.Reset();
3444 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3445
3446 // Set up two active sockets in "b".
3447 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523448 TestCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463449 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3450 params_,
3451 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523452 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463453 pool_.get(),
3454 BoundNetLog()));
3455 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3456 params_,
3457 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523458 callback2.callback(),
[email protected]dcbe168a2010-12-02 03:14:463459 pool_.get(),
3460 BoundNetLog()));
3461
3462 ASSERT_EQ(OK, callback1.WaitForResult());
3463 ASSERT_EQ(OK, callback2.WaitForResult());
3464 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103465 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463466 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3467
3468 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3469 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3470 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3471 // sockets for "a", and "b" should still have 2 active sockets.
3472
3473 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3474 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103475 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463476 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3477 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3478 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103479 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463480 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3481 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3482
3483 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3484 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3485 // "a" should result in closing 1 for "b".
3486 handle1.Reset();
3487 handle2.Reset();
3488 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3489 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3490
3491 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3492 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103493 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463494 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3495 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3496 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103497 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463498 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3499 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3500}
3501
[email protected]b7b8be42011-07-12 12:46:413502TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073503 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3504 pool_->EnableConnectBackupJobs();
3505
3506 // Make the ConnectJob hang until it times out, shorten the timeout.
3507 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3508 connect_job_factory_->set_timeout_duration(
3509 base::TimeDelta::FromMilliseconds(500));
3510 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3511 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103512 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073513 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073514
[email protected]b7b8be42011-07-12 12:46:413515 // Verify the backup timer doesn't create a backup job, by making
3516 // the backup job a pending job instead of a waiting job, so it
3517 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073518 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5761ab9c2012-02-04 16:44:533519 MessageLoop::current()->PostDelayedTask(
3520 FROM_HERE, MessageLoop::QuitClosure(), base::TimeDelta::FromSeconds(1));
[email protected]b7b8be42011-07-12 12:46:413521 MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073522 EXPECT_FALSE(pool_->HasGroup("a"));
3523}
3524
[email protected]b7b8be42011-07-12 12:46:413525TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073526 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3527 pool_->EnableConnectBackupJobs();
3528
3529 // Make the ConnectJob hang forever.
3530 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3531 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3532 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103533 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073534 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]b4c62eb2012-11-14 18:36:513535 MessageLoop::current()->RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073536
3537 // Make the backup job be a pending job, so it completes normally.
3538 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3539 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523540 TestCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073541 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3542 params_,
3543 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523544 callback.callback(),
[email protected]a9fc8fc2011-05-10 02:41:073545 pool_.get(),
3546 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413547 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073548 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103549 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073550 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3551 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3552 ASSERT_EQ(OK, callback.WaitForResult());
3553
3554 // The hung connect job should still be there, but everything else should be
3555 // complete.
3556 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103557 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073558 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3559 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3560}
3561
[email protected]58e562f2013-04-22 17:32:203562class MockLayeredPool : public LayeredPool {
3563 public:
3564 MockLayeredPool(TestClientSocketPool* pool,
3565 const std::string& group_name)
3566 : pool_(pool),
3567 params_(new TestSocketParams),
3568 group_name_(group_name),
3569 can_release_connection_(true) {
3570 pool_->AddLayeredPool(this);
3571 }
3572
3573 ~MockLayeredPool() {
3574 pool_->RemoveLayeredPool(this);
3575 }
3576
3577 int RequestSocket(TestClientSocketPool* pool) {
3578 return handle_.Init(group_name_, params_, kDefaultPriority,
3579 callback_.callback(), pool, BoundNetLog());
3580 }
3581
3582 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
3583 params_->set_ignore_limits(true);
3584 return handle_.Init(group_name_, params_, kDefaultPriority,
3585 callback_.callback(), pool, BoundNetLog());
3586 }
3587
3588 bool ReleaseOneConnection() {
3589 if (!handle_.is_initialized() || !can_release_connection_) {
3590 return false;
3591 }
3592 handle_.socket()->Disconnect();
3593 handle_.Reset();
3594 return true;
3595 }
3596
3597 void set_can_release_connection(bool can_release_connection) {
3598 can_release_connection_ = can_release_connection;
3599 }
3600
3601 MOCK_METHOD0(CloseOneIdleConnection, bool());
3602
3603 private:
3604 TestClientSocketPool* const pool_;
3605 scoped_refptr<TestSocketParams> params_;
3606 ClientSocketHandle handle_;
3607 TestCompletionCallback callback_;
3608 const std::string group_name_;
3609 bool can_release_connection_;
3610};
3611
3612TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3613 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3614 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3615
3616 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3617 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3618 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3619 .WillOnce(Return(false));
3620 EXPECT_FALSE(pool_->CloseOneIdleConnectionInLayeredPool());
3621}
3622
3623TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3624 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3625 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3626
3627 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3628 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3629 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3630 .WillOnce(Invoke(&mock_layered_pool,
3631 &MockLayeredPool::ReleaseOneConnection));
3632 EXPECT_TRUE(pool_->CloseOneIdleConnectionInLayeredPool());
3633}
3634
3635// Tests the basic case of closing an idle socket in a higher layered pool when
3636// a new request is issued and the lower layer pool is stalled.
3637TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3638 CreatePool(1, 1);
3639 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3640
3641 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3642 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3643 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3644 .WillOnce(Invoke(&mock_layered_pool,
3645 &MockLayeredPool::ReleaseOneConnection));
3646 ClientSocketHandle handle;
3647 TestCompletionCallback callback;
3648 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3649 params_,
3650 kDefaultPriority,
3651 callback.callback(),
3652 pool_.get(),
3653 BoundNetLog()));
3654 EXPECT_EQ(OK, callback.WaitForResult());
3655}
3656
3657// Same as above, but the idle socket is in the same group as the stalled
3658// socket, and closes the only other request in its group when closing requests
3659// in higher layered pools. This generally shouldn't happen, but it may be
3660// possible if a higher level pool issues a request and the request is
3661// subsequently cancelled. Even if it's not possible, best not to crash.
3662TEST_F(ClientSocketPoolBaseTest,
3663 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
3664 CreatePool(2, 2);
3665 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3666
3667 // Need a socket in another group for the pool to be stalled (If a group
3668 // has the maximum number of connections already, it's not stalled).
3669 ClientSocketHandle handle1;
3670 TestCompletionCallback callback1;
3671 EXPECT_EQ(OK, handle1.Init("group1",
3672 params_,
3673 kDefaultPriority,
3674 callback1.callback(),
3675 pool_.get(),
3676 BoundNetLog()));
3677
3678 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3679 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3680 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3681 .WillOnce(Invoke(&mock_layered_pool,
3682 &MockLayeredPool::ReleaseOneConnection));
3683 ClientSocketHandle handle;
3684 TestCompletionCallback callback2;
3685 EXPECT_EQ(ERR_IO_PENDING, handle.Init("group2",
3686 params_,
3687 kDefaultPriority,
3688 callback2.callback(),
3689 pool_.get(),
3690 BoundNetLog()));
3691 EXPECT_EQ(OK, callback2.WaitForResult());
3692}
3693
3694// Tests the case when an idle socket can be closed when a new request is
3695// issued, and the new request belongs to a group that was previously stalled.
3696TEST_F(ClientSocketPoolBaseTest,
3697 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3698 CreatePool(2, 2);
3699 std::list<TestConnectJob::JobType> job_types;
3700 job_types.push_back(TestConnectJob::kMockJob);
3701 job_types.push_back(TestConnectJob::kMockJob);
3702 job_types.push_back(TestConnectJob::kMockJob);
3703 job_types.push_back(TestConnectJob::kMockJob);
3704 connect_job_factory_->set_job_types(&job_types);
3705
3706 ClientSocketHandle handle1;
3707 TestCompletionCallback callback1;
3708 EXPECT_EQ(OK, handle1.Init("group1",
3709 params_,
3710 kDefaultPriority,
3711 callback1.callback(),
3712 pool_.get(),
3713 BoundNetLog()));
3714
3715 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3716 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3717 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3718 .WillRepeatedly(Invoke(&mock_layered_pool,
3719 &MockLayeredPool::ReleaseOneConnection));
3720 mock_layered_pool.set_can_release_connection(false);
3721
3722 // The third request is made when the socket pool is in a stalled state.
3723 ClientSocketHandle handle3;
3724 TestCompletionCallback callback3;
3725 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
3726 params_,
3727 kDefaultPriority,
3728 callback3.callback(),
3729 pool_.get(),
3730 BoundNetLog()));
3731
3732 base::RunLoop().RunUntilIdle();
3733 EXPECT_FALSE(callback3.have_result());
3734
3735 // The fourth request is made when the pool is no longer stalled. The third
3736 // request should be serviced first, since it was issued first and has the
3737 // same priority.
3738 mock_layered_pool.set_can_release_connection(true);
3739 ClientSocketHandle handle4;
3740 TestCompletionCallback callback4;
3741 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
3742 params_,
3743 kDefaultPriority,
3744 callback4.callback(),
3745 pool_.get(),
3746 BoundNetLog()));
3747 EXPECT_EQ(OK, callback3.WaitForResult());
3748 EXPECT_FALSE(callback4.have_result());
3749
3750 // Closing a handle should free up another socket slot.
3751 handle1.Reset();
3752 EXPECT_EQ(OK, callback4.WaitForResult());
3753}
3754
3755// Tests the case when an idle socket can be closed when a new request is
3756// issued, and the new request belongs to a group that was previously stalled.
3757//
3758// The two differences from the above test are that the stalled requests are not
3759// in the same group as the layered pool's request, and the the fourth request
3760// has a higher priority than the third one, so gets a socket first.
3761TEST_F(ClientSocketPoolBaseTest,
3762 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
3763 CreatePool(2, 2);
3764 std::list<TestConnectJob::JobType> job_types;
3765 job_types.push_back(TestConnectJob::kMockJob);
3766 job_types.push_back(TestConnectJob::kMockJob);
3767 job_types.push_back(TestConnectJob::kMockJob);
3768 job_types.push_back(TestConnectJob::kMockJob);
3769 connect_job_factory_->set_job_types(&job_types);
3770
3771 ClientSocketHandle handle1;
3772 TestCompletionCallback callback1;
3773 EXPECT_EQ(OK, handle1.Init("group1",
3774 params_,
3775 kDefaultPriority,
3776 callback1.callback(),
3777 pool_.get(),
3778 BoundNetLog()));
3779
3780 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3781 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3782 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3783 .WillRepeatedly(Invoke(&mock_layered_pool,
3784 &MockLayeredPool::ReleaseOneConnection));
3785 mock_layered_pool.set_can_release_connection(false);
3786
3787 // The third request is made when the socket pool is in a stalled state.
3788 ClientSocketHandle handle3;
3789 TestCompletionCallback callback3;
3790 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("group3",
3791 params_,
3792 MEDIUM,
3793 callback3.callback(),
3794 pool_.get(),
3795 BoundNetLog()));
3796
3797 base::RunLoop().RunUntilIdle();
3798 EXPECT_FALSE(callback3.have_result());
3799
3800 // The fourth request is made when the pool is no longer stalled. This
3801 // request has a higher priority than the third request, so is serviced first.
3802 mock_layered_pool.set_can_release_connection(true);
3803 ClientSocketHandle handle4;
3804 TestCompletionCallback callback4;
3805 EXPECT_EQ(ERR_IO_PENDING, handle4.Init("group3",
3806 params_,
3807 HIGHEST,
3808 callback4.callback(),
3809 pool_.get(),
3810 BoundNetLog()));
3811 EXPECT_EQ(OK, callback4.WaitForResult());
3812 EXPECT_FALSE(callback3.have_result());
3813
3814 // Closing a handle should free up another socket slot.
3815 handle1.Reset();
3816 EXPECT_EQ(OK, callback3.WaitForResult());
3817}
3818
3819TEST_F(ClientSocketPoolBaseTest,
3820 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
3821 CreatePool(1, 1);
3822 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3823
3824 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
3825 EXPECT_EQ(OK, mock_layered_pool1.RequestSocket(pool_.get()));
3826 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
3827 .WillRepeatedly(Invoke(&mock_layered_pool1,
3828 &MockLayeredPool::ReleaseOneConnection));
3829 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
3830 EXPECT_EQ(OK, mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()));
3831 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
3832 .WillRepeatedly(Invoke(&mock_layered_pool2,
3833 &MockLayeredPool::ReleaseOneConnection));
3834 ClientSocketHandle handle;
3835 TestCompletionCallback callback;
3836 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3837 params_,
3838 kDefaultPriority,
3839 callback.callback(),
3840 pool_.get(),
3841 BoundNetLog()));
3842 EXPECT_EQ(OK, callback.WaitForResult());
3843}
3844
3845
[email protected]f6d1d6eb2009-06-24 20:16:093846} // namespace
3847
3848} // namespace net