blob: bc64306db87f94eb9ee108eac5ca5e1f47a234b1 [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]6ea7b152011-12-21 21:21:13262 ALLOW_THIS_IN_INITIALIZER_LIST(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),
1444 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
1445 base::Bind(&RequestSocketCallback::OnComplete,
1446 base::Unretained(this)))) {
1447 }
[email protected]f6d1d6eb2009-06-24 20:16:091448
[email protected]6ecf2b92011-12-15 01:14:521449 virtual ~RequestSocketCallback() {}
1450
1451 const CompletionCallback& callback() const { return callback_; }
1452
1453 private:
1454 void OnComplete(int result) {
1455 SetResult(result);
1456 ASSERT_EQ(OK, result);
[email protected]f6d1d6eb2009-06-24 20:16:091457
1458 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581459 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111460
1461 // Don't allow reuse of the socket. Disconnect it and then release it and
1462 // run through the MessageLoop once to get it completely released.
1463 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091464 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111465 {
[email protected]b5717a42012-02-14 19:33:521466 // TODO: Resolve conflicting intentions of stopping recursion with the
[email protected]b4c62eb2012-11-14 18:36:511467 // |!within_callback_| test (above) and the call to |RunUntilIdle()|
[email protected]b5717a42012-02-14 19:33:521468 // below. http://crbug.com/114130.
1469 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
[email protected]b4c62eb2012-11-14 18:36:511470 MessageLoop::current()->RunUntilIdle();
[email protected]5edbf8d2010-01-13 18:44:111471 }
[email protected]f6d1d6eb2009-06-24 20:16:091472 within_callback_ = true;
[email protected]6ecf2b92011-12-15 01:14:521473 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271474 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131475 int rv = handle_->Init("a",
1476 params,
1477 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521478 next_job_callback.callback(),
[email protected]2431756e2010-09-29 20:26:131479 pool_,
1480 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581481 switch (next_job_type_) {
1482 case TestConnectJob::kMockJob:
1483 EXPECT_EQ(OK, rv);
1484 break;
1485 case TestConnectJob::kMockPendingJob:
1486 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471487
1488 // For pending jobs, wait for new socket to be created. This makes
1489 // sure there are no more pending operations nor any unclosed sockets
1490 // when the test finishes.
1491 // We need to give it a little bit of time to run, so that all the
1492 // operations that happen on timers (e.g. cleanup of idle
1493 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111494 {
[email protected]b5717a42012-02-14 19:33:521495 MessageLoop::ScopedNestableTaskAllower allow(
[email protected]5edbf8d2010-01-13 18:44:111496 MessageLoop::current());
[email protected]26b9973962012-01-28 00:57:001497 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]5edbf8d2010-01-13 18:44:111498 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1499 }
[email protected]2ab05b52009-07-01 23:57:581500 break;
1501 default:
1502 FAIL() << "Unexpected job type: " << next_job_type_;
1503 break;
1504 }
[email protected]f6d1d6eb2009-06-24 20:16:091505 }
1506 }
1507
[email protected]f6d1d6eb2009-06-24 20:16:091508 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131509 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091510 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581511 TestConnectJobFactory* const test_connect_job_factory_;
1512 TestConnectJob::JobType next_job_type_;
[email protected]6ecf2b92011-12-15 01:14:521513 CompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091514};
1515
[email protected]2ab05b52009-07-01 23:57:581516TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531517 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201518
[email protected]0b7648c2009-07-06 20:14:011519 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061520 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581521 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061522 &handle, pool_.get(), connect_job_factory_,
1523 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131524 int rv = handle.Init("a",
1525 params_,
1526 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521527 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131528 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211529 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091530 ASSERT_EQ(ERR_IO_PENDING, rv);
1531
1532 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581533}
[email protected]f6d1d6eb2009-06-24 20:16:091534
[email protected]2ab05b52009-07-01 23:57:581535TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531536 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201537
[email protected]0b7648c2009-07-06 20:14:011538 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061539 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581540 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061541 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131542 int rv = handle.Init("a",
1543 params_,
1544 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521545 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131546 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211547 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581548 ASSERT_EQ(ERR_IO_PENDING, rv);
1549
1550 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091551}
1552
1553// Make sure that pending requests get serviced after active requests get
1554// cancelled.
[email protected]ab838892009-06-30 18:49:051555TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531556 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201557
[email protected]0b7648c2009-07-06 20:14:011558 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091559
[email protected]c9d6a1d2009-07-14 16:15:201560 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));
1566 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091567
[email protected]c9d6a1d2009-07-14 16:15:201568 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1569 // Let's cancel them.
1570 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131571 ASSERT_FALSE(request(i)->handle()->is_initialized());
1572 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091573 }
1574
[email protected]f6d1d6eb2009-06-24 20:16:091575 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131576 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1577 EXPECT_EQ(OK, request(i)->WaitForResult());
1578 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091579 }
1580
[email protected]2431756e2010-09-29 20:26:131581 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1582 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091583}
1584
1585// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051586TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531587 const size_t kMaxSockets = 5;
1588 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201589
[email protected]0b7648c2009-07-06 20:14:011590 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091591
[email protected]211d21722009-07-22 15:48:531592 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1593 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091594
1595 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531596 for (size_t i = 0; i < kNumberOfRequests; ++i)
1597 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091598
[email protected]211d21722009-07-22 15:48:531599 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131600 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091601}
1602
[email protected]5fc08e32009-07-15 17:09:571603TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531604 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571605
1606 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1607
[email protected]2431756e2010-09-29 20:26:131608 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521609 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131610 int rv = handle.Init("a",
1611 params_,
1612 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521613 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131614 pool_.get(),
1615 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571616 EXPECT_EQ(ERR_IO_PENDING, rv);
1617
1618 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131619 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571620
[email protected]2431756e2010-09-29 20:26:131621 rv = handle.Init("a",
1622 params_,
1623 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521624 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131625 pool_.get(),
1626 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571627 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131628 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571629
[email protected]2431756e2010-09-29 20:26:131630 EXPECT_FALSE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:481631 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]5fc08e32009-07-15 17:09:571632 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1633}
1634
[email protected]2b7523d2009-07-29 20:29:231635// Regression test for http://crbug.com/17985.
1636TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1637 const int kMaxSockets = 3;
1638 const int kMaxSocketsPerGroup = 2;
1639 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1640
[email protected]ac790b42009-12-02 04:31:311641 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231642
1643 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1644 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1645
1646 // This is going to be a pending request in an otherwise empty group.
1647 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1648
1649 // Reach the maximum socket limit.
1650 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1651
1652 // Create a stalled group with high priorities.
1653 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1654 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231655
[email protected]eb5a99382010-07-11 03:18:261656 // Release the first two sockets from "a". Because this is a keepalive,
1657 // the first release will unblock the pending request for "a". The
1658 // second release will unblock a request for "c", becaue it is the next
1659 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131660 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1661 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231662
1663 // Closing idle sockets should not get us into trouble, but in the bug
1664 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411665 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541666 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261667
[email protected]b4c62eb2012-11-14 18:36:511668 MessageLoop::current()->RunUntilIdle(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231669}
1670
[email protected]4d3b05d2010-01-27 21:27:291671TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531672 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571673
1674 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131675 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521676 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291677 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:131678 int rv = handle.Init("a",
1679 params_,
1680 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521681 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131682 pool_.get(),
1683 log.bound());
[email protected]5fc08e32009-07-15 17:09:571684 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131685 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]034df0f32013-01-07 23:17:481686 TestLoadTimingInfoNotConnected(handle);
1687
[email protected]2431756e2010-09-29 20:26:131688 EXPECT_EQ(OK, callback.WaitForResult());
1689 EXPECT_TRUE(handle.is_initialized());
1690 EXPECT_TRUE(handle.socket());
[email protected]034df0f32013-01-07 23:17:481691 TestLoadTimingInfoConnectedNotReused(handle);
1692
[email protected]2431756e2010-09-29 20:26:131693 handle.Reset();
[email protected]034df0f32013-01-07 23:17:481694 TestLoadTimingInfoNotConnected(handle);
[email protected]fd7b7c92009-08-20 19:38:301695
[email protected]333bdf62012-06-08 22:57:291696 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401697 log.GetEntries(&entries);
1698
1699 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461700 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401701 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171702 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401703 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171704 NetLog::PHASE_NONE));
1705 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401706 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171707 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461708 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401709 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571710}
1711
[email protected]4d3b05d2010-01-27 21:27:291712TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571713 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531714 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571715
1716 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131717 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521718 TestCompletionCallback callback;
[email protected]333bdf62012-06-08 22:57:291719 CapturingBoundNetLog log;
[email protected]e60e47a2010-07-14 03:37:181720 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131721 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431722 HttpResponseInfo info;
[email protected]007b3f82013-04-09 08:46:451723 info.headers = new HttpResponseHeaders(std::string());
[email protected]2431756e2010-09-29 20:26:131724 handle.set_ssl_error_response_info(info);
1725 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1726 params_,
1727 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521728 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131729 pool_.get(),
1730 log.bound()));
1731 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1732 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1733 EXPECT_FALSE(handle.is_ssl_error());
1734 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301735
[email protected]333bdf62012-06-08 22:57:291736 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401737 log.GetEntries(&entries);
1738
1739 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461740 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401741 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171742 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401743 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171744 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321745 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401746 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571747}
1748
[email protected]4d3b05d2010-01-27 21:27:291749TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101750 // TODO(eroman): Add back the log expectations! Removed them because the
1751 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531752 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571753
1754 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131755 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521756 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131757 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521758 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571759
[email protected]2431756e2010-09-29 20:26:131760 EXPECT_EQ(ERR_IO_PENDING,
1761 handle.Init("a",
1762 params_,
1763 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521764 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131765 pool_.get(),
1766 BoundNetLog()));
[email protected]333bdf62012-06-08 22:57:291767 CapturingBoundNetLog log2;
[email protected]2431756e2010-09-29 20:26:131768 EXPECT_EQ(ERR_IO_PENDING,
1769 handle2.Init("a",
1770 params_,
1771 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521772 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131773 pool_.get(),
1774 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571775
[email protected]2431756e2010-09-29 20:26:131776 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571777
[email protected]fd7b7c92009-08-20 19:38:301778
1779 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301780
[email protected]2431756e2010-09-29 20:26:131781 EXPECT_EQ(OK, callback2.WaitForResult());
1782 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301783
1784 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531785 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571786}
1787
[email protected]4d3b05d2010-01-27 21:27:291788TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341789 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1790
[email protected]17a0c6c2009-08-04 00:07:041791 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1792
[email protected]ac790b42009-12-02 04:31:311793 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1794 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1795 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1796 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341797
1798 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131799 (*requests())[2]->handle()->Reset();
1800 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341801 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1802
[email protected]2431756e2010-09-29 20:26:131803 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341804 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1805
[email protected]2431756e2010-09-29 20:26:131806 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261807 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341808}
1809
[email protected]5fc08e32009-07-15 17:09:571810// When requests and ConnectJobs are not coupled, the request will get serviced
1811// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291812TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531813 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571814
1815 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321816 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571817
[email protected]2431756e2010-09-29 20:26:131818 std::vector<TestSocketRequest*> request_order;
1819 size_t completion_count; // unused
1820 TestSocketRequest req1(&request_order, &completion_count);
1821 int rv = req1.handle()->Init("a",
1822 params_,
1823 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521824 req1.callback(), pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211825 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571826 EXPECT_EQ(ERR_IO_PENDING, rv);
1827 EXPECT_EQ(OK, req1.WaitForResult());
1828
1829 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1830 // without a job.
1831 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1832
[email protected]2431756e2010-09-29 20:26:131833 TestSocketRequest req2(&request_order, &completion_count);
1834 rv = req2.handle()->Init("a",
1835 params_,
1836 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521837 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131838 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211839 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571840 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131841 TestSocketRequest req3(&request_order, &completion_count);
1842 rv = req3.handle()->Init("a",
1843 params_,
1844 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521845 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131846 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211847 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571848 EXPECT_EQ(ERR_IO_PENDING, rv);
1849
1850 // Both Requests 2 and 3 are pending. We release socket 1 which should
1851 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331852 req1.handle()->Reset();
[email protected]b4c62eb2012-11-14 18:36:511853 MessageLoop::current()->RunUntilIdle(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331854 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571855 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331856 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571857
1858 // Signal job 2, which should service request 3.
1859
1860 client_socket_factory_.SignalJobs();
1861 EXPECT_EQ(OK, req3.WaitForResult());
1862
[email protected]2431756e2010-09-29 20:26:131863 ASSERT_EQ(3U, request_order.size());
1864 EXPECT_EQ(&req1, request_order[0]);
1865 EXPECT_EQ(&req2, request_order[1]);
1866 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571867 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1868}
1869
1870// The requests are not coupled to the jobs. So, the requests should finish in
1871// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291872TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531873 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571874 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321875 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571876
[email protected]2431756e2010-09-29 20:26:131877 std::vector<TestSocketRequest*> request_order;
1878 size_t completion_count; // unused
1879 TestSocketRequest req1(&request_order, &completion_count);
1880 int rv = req1.handle()->Init("a",
1881 params_,
1882 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521883 req1.callback(),
[email protected]2431756e2010-09-29 20:26:131884 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211885 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571886 EXPECT_EQ(ERR_IO_PENDING, rv);
1887
[email protected]2431756e2010-09-29 20:26:131888 TestSocketRequest req2(&request_order, &completion_count);
1889 rv = req2.handle()->Init("a",
1890 params_,
1891 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521892 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131893 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211894 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571895 EXPECT_EQ(ERR_IO_PENDING, rv);
1896
1897 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321898 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571899
[email protected]2431756e2010-09-29 20:26:131900 TestSocketRequest req3(&request_order, &completion_count);
1901 rv = req3.handle()->Init("a",
1902 params_,
1903 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521904 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131905 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211906 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571907 EXPECT_EQ(ERR_IO_PENDING, rv);
1908
1909 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1910 EXPECT_EQ(OK, req2.WaitForResult());
1911 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1912
[email protected]2431756e2010-09-29 20:26:131913 ASSERT_EQ(3U, request_order.size());
1914 EXPECT_EQ(&req1, request_order[0]);
1915 EXPECT_EQ(&req2, request_order[1]);
1916 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571917}
1918
[email protected]e6ec67b2010-06-16 00:12:461919TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531920 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571921 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321922 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571923
[email protected]2431756e2010-09-29 20:26:131924 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521925 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131926 int rv = handle.Init("a",
1927 params_,
1928 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521929 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131930 pool_.get(),
1931 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571932 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131933 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571934
[email protected]b4c62eb2012-11-14 18:36:511935 MessageLoop::current()->RunUntilIdle();
[email protected]5fc08e32009-07-15 17:09:571936
[email protected]2431756e2010-09-29 20:26:131937 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521938 TestCompletionCallback callback2;
1939 rv = handle2.Init("a", params_, kDefaultPriority, callback2.callback(),
1940 pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571941 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131942 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1943 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571944}
1945
[email protected]e772db3f2010-07-12 18:11:131946TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1947 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1948 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1949
[email protected]2431756e2010-09-29 20:26:131950 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521951 TestCompletionCallback callback;
1952 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
1953 handle.Init("a", params_, kDefaultPriority, callback.callback(),
1954 pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:131955 EXPECT_TRUE(handle.is_initialized());
1956 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131957}
1958
1959TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1960 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1961
1962 connect_job_factory_->set_job_type(
1963 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131964 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521965 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131966 EXPECT_EQ(ERR_IO_PENDING,
1967 handle.Init("a",
1968 params_,
1969 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521970 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131971 pool_.get(),
1972 BoundNetLog()));
1973 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1974 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1975 EXPECT_TRUE(handle.is_initialized());
1976 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131977}
1978
[email protected]e60e47a2010-07-14 03:37:181979TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1980 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1981 connect_job_factory_->set_job_type(
1982 TestConnectJob::kMockAdditionalErrorStateJob);
1983
[email protected]2431756e2010-09-29 20:26:131984 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521985 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131986 EXPECT_EQ(ERR_CONNECTION_FAILED,
1987 handle.Init("a",
1988 params_,
1989 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521990 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131991 pool_.get(),
1992 BoundNetLog()));
1993 EXPECT_FALSE(handle.is_initialized());
1994 EXPECT_FALSE(handle.socket());
1995 EXPECT_TRUE(handle.is_ssl_error());
1996 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181997}
1998
1999TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2000 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2001
2002 connect_job_factory_->set_job_type(
2003 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132004 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522005 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132006 EXPECT_EQ(ERR_IO_PENDING,
2007 handle.Init("a",
2008 params_,
2009 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522010 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132011 pool_.get(),
2012 BoundNetLog()));
2013 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2014 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
2015 EXPECT_FALSE(handle.is_initialized());
2016 EXPECT_FALSE(handle.socket());
2017 EXPECT_TRUE(handle.is_ssl_error());
2018 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182019}
2020
[email protected]e7b1c6d2c2012-05-05 00:54:032021// Make sure we can reuse sockets when the cleanup timer is disabled.
2022TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerReuse) {
[email protected]64770b7d2011-11-16 04:30:412023 // Disable cleanup timer.
2024 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2025
2026 CreatePoolWithIdleTimeouts(
2027 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032028 base::TimeDelta(), // Time out unused sockets immediately.
2029 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2030
2031 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2032
2033 ClientSocketHandle handle;
2034 TestCompletionCallback callback;
2035 int rv = handle.Init("a",
2036 params_,
2037 LOWEST,
2038 callback.callback(),
2039 pool_.get(),
2040 BoundNetLog());
2041 ASSERT_EQ(ERR_IO_PENDING, rv);
2042 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2043 ASSERT_EQ(OK, callback.WaitForResult());
2044
2045 // Use and release the socket.
2046 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]034df0f32013-01-07 23:17:482047 TestLoadTimingInfoConnectedNotReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032048 handle.Reset();
2049
2050 // Should now have one idle socket.
2051 ASSERT_EQ(1, pool_->IdleSocketCount());
2052
2053 // Request a new socket. This should reuse the old socket and complete
2054 // synchronously.
[email protected]333bdf62012-06-08 22:57:292055 CapturingBoundNetLog log;
[email protected]e7b1c6d2c2012-05-05 00:54:032056 rv = handle.Init("a",
2057 params_,
2058 LOWEST,
2059 CompletionCallback(),
2060 pool_.get(),
2061 log.bound());
2062 ASSERT_EQ(OK, rv);
2063 EXPECT_TRUE(handle.is_reused());
[email protected]034df0f32013-01-07 23:17:482064 TestLoadTimingInfoConnectedReused(handle);
[email protected]e7b1c6d2c2012-05-05 00:54:032065
2066 ASSERT_TRUE(pool_->HasGroup("a"));
2067 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2068 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2069
[email protected]333bdf62012-06-08 22:57:292070 CapturingNetLog::CapturedEntryList entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032071 log.GetEntries(&entries);
2072 EXPECT_TRUE(LogContainsEntryWithType(
2073 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2074}
2075
2076// Make sure we cleanup old unused sockets when the cleanup timer is disabled.
2077TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerNoReuse) {
2078 // Disable cleanup timer.
2079 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2080
2081 CreatePoolWithIdleTimeouts(
2082 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2083 base::TimeDelta(), // Time out unused sockets immediately
2084 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412085
2086 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2087
2088 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2089
2090 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522091 TestCompletionCallback callback;
[email protected]64770b7d2011-11-16 04:30:412092 int rv = handle.Init("a",
2093 params_,
2094 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522095 callback.callback(),
[email protected]64770b7d2011-11-16 04:30:412096 pool_.get(),
2097 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032098 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412099 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2100
2101 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522102 TestCompletionCallback callback2;
[email protected]64770b7d2011-11-16 04:30:412103 rv = handle2.Init("a",
2104 params_,
2105 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522106 callback2.callback(),
[email protected]64770b7d2011-11-16 04:30:412107 pool_.get(),
2108 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032109 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412110 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2111
2112 // Cancel one of the requests. Wait for the other, which will get the first
2113 // job. Release the socket. Run the loop again to make sure the second
2114 // socket is sitting idle and the first one is released (since ReleaseSocket()
2115 // just posts a DoReleaseSocket() task).
2116
2117 handle.Reset();
[email protected]e7b1c6d2c2012-05-05 00:54:032118 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412119 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552120 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412121 handle2.Reset();
2122
[email protected]e7b1c6d2c2012-05-05 00:54:032123 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2124 // actually become pending until 2ms after they have been created. In order
2125 // to flush all tasks, we need to wait so that we know there are no
2126 // soon-to-be-pending tasks waiting.
2127 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]b4c62eb2012-11-14 18:36:512128 MessageLoop::current()->RunUntilIdle();
[email protected]64770b7d2011-11-16 04:30:412129
[email protected]e7b1c6d2c2012-05-05 00:54:032130 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412131 ASSERT_EQ(2, pool_->IdleSocketCount());
2132
2133 // Request a new socket. This should cleanup the unused and timed out ones.
2134 // A new socket will be created rather than reusing the idle one.
[email protected]333bdf62012-06-08 22:57:292135 CapturingBoundNetLog log;
[email protected]6ecf2b92011-12-15 01:14:522136 TestCompletionCallback callback3;
[email protected]64770b7d2011-11-16 04:30:412137 rv = handle.Init("a",
2138 params_,
2139 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522140 callback3.callback(),
[email protected]64770b7d2011-11-16 04:30:412141 pool_.get(),
2142 log.bound());
[email protected]e7b1c6d2c2012-05-05 00:54:032143 ASSERT_EQ(ERR_IO_PENDING, rv);
2144 ASSERT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412145 EXPECT_FALSE(handle.is_reused());
2146
[email protected]e7b1c6d2c2012-05-05 00:54:032147 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412148 ASSERT_TRUE(pool_->HasGroup("a"));
2149 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2150 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2151
[email protected]333bdf62012-06-08 22:57:292152 CapturingNetLog::CapturedEntryList entries;
[email protected]64770b7d2011-11-16 04:30:412153 log.GetEntries(&entries);
2154 EXPECT_FALSE(LogContainsEntryWithType(
2155 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2156}
2157
[email protected]4d3b05d2010-01-27 21:27:292158TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162159 CreatePoolWithIdleTimeouts(
2160 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2161 base::TimeDelta(), // Time out unused sockets immediately.
2162 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2163
2164 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2165
2166 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2167
[email protected]2431756e2010-09-29 20:26:132168 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522169 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132170 int rv = handle.Init("a",
2171 params_,
2172 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522173 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132174 pool_.get(),
2175 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162176 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132177 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162178
[email protected]2431756e2010-09-29 20:26:132179 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522180 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132181 rv = handle2.Init("a",
2182 params_,
2183 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522184 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132185 pool_.get(),
2186 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162187 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132188 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162189
2190 // Cancel one of the requests. Wait for the other, which will get the first
2191 // job. Release the socket. Run the loop again to make sure the second
2192 // socket is sitting idle and the first one is released (since ReleaseSocket()
2193 // just posts a DoReleaseSocket() task).
2194
[email protected]2431756e2010-09-29 20:26:132195 handle.Reset();
2196 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012197 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552198 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]2431756e2010-09-29 20:26:132199 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472200
2201 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2202 // actually become pending until 2ms after they have been created. In order
2203 // to flush all tasks, we need to wait so that we know there are no
2204 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:002205 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]b4c62eb2012-11-14 18:36:512206 MessageLoop::current()->RunUntilIdle();
[email protected]9bf28db2009-08-29 01:35:162207
2208 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042209
[email protected]9bf28db2009-08-29 01:35:162210 // Invoke the idle socket cleanup check. Only one socket should be left, the
2211 // used socket. Request it to make sure that it's used.
2212
2213 pool_->CleanupTimedOutIdleSockets();
[email protected]333bdf62012-06-08 22:57:292214 CapturingBoundNetLog log;
[email protected]2431756e2010-09-29 20:26:132215 rv = handle.Init("a",
2216 params_,
2217 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522218 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132219 pool_.get(),
2220 log.bound());
[email protected]9bf28db2009-08-29 01:35:162221 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132222 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402223
[email protected]333bdf62012-06-08 22:57:292224 CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402225 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152226 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402227 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162228}
2229
[email protected]2041cf342010-02-19 03:15:592230// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162231// because of multiple releasing disconnected sockets.
2232TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2233 CreatePoolWithIdleTimeouts(
2234 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2235 base::TimeDelta(), // Time out unused sockets immediately.
2236 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2237
2238 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2239
2240 // Startup 4 connect jobs. Two of them will be pending.
2241
[email protected]2431756e2010-09-29 20:26:132242 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522243 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132244 int rv = handle.Init("a",
2245 params_,
2246 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522247 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132248 pool_.get(),
2249 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162250 EXPECT_EQ(OK, rv);
2251
[email protected]2431756e2010-09-29 20:26:132252 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522253 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132254 rv = handle2.Init("a",
2255 params_,
2256 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522257 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132258 pool_.get(),
2259 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162260 EXPECT_EQ(OK, rv);
2261
[email protected]2431756e2010-09-29 20:26:132262 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522263 TestCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132264 rv = handle3.Init("a",
2265 params_,
2266 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522267 callback3.callback(),
[email protected]2431756e2010-09-29 20:26:132268 pool_.get(),
2269 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162270 EXPECT_EQ(ERR_IO_PENDING, rv);
2271
[email protected]2431756e2010-09-29 20:26:132272 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522273 TestCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132274 rv = handle4.Init("a",
2275 params_,
2276 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522277 callback4.callback(),
[email protected]2431756e2010-09-29 20:26:132278 pool_.get(),
2279 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162280 EXPECT_EQ(ERR_IO_PENDING, rv);
2281
2282 // Release two disconnected sockets.
2283
[email protected]2431756e2010-09-29 20:26:132284 handle.socket()->Disconnect();
2285 handle.Reset();
2286 handle2.socket()->Disconnect();
2287 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162288
[email protected]2431756e2010-09-29 20:26:132289 EXPECT_EQ(OK, callback3.WaitForResult());
2290 EXPECT_FALSE(handle3.is_reused());
2291 EXPECT_EQ(OK, callback4.WaitForResult());
2292 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162293}
2294
[email protected]d7027bb2010-05-10 18:58:542295// Regression test for http://crbug.com/42267.
2296// When DoReleaseSocket() is processed for one socket, it is blocked because the
2297// other stalled groups all have releasing sockets, so no progress can be made.
2298TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2299 CreatePoolWithIdleTimeouts(
2300 4 /* socket limit */, 4 /* socket limit per group */,
2301 base::TimeDelta(), // Time out unused sockets immediately.
2302 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2303
2304 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2305
2306 // Max out the socket limit with 2 per group.
2307
[email protected]2431756e2010-09-29 20:26:132308 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522309 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132310 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522311 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542312
2313 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132314 EXPECT_EQ(OK, handle_a[i].Init("a",
2315 params_,
2316 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522317 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132318 pool_.get(),
2319 BoundNetLog()));
2320 EXPECT_EQ(OK, handle_b[i].Init("b",
2321 params_,
2322 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522323 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132324 pool_.get(),
2325 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542326 }
[email protected]b89f7e42010-05-20 20:37:002327
[email protected]d7027bb2010-05-10 18:58:542328 // Make 4 pending requests, 2 per group.
2329
2330 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132331 EXPECT_EQ(ERR_IO_PENDING,
2332 handle_a[i].Init("a",
2333 params_,
2334 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522335 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132336 pool_.get(),
2337 BoundNetLog()));
2338 EXPECT_EQ(ERR_IO_PENDING,
2339 handle_b[i].Init("b",
2340 params_,
2341 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522342 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132343 pool_.get(),
2344 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542345 }
2346
2347 // Release b's socket first. The order is important, because in
2348 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2349 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2350 // first, which has a releasing socket, so it refuses to start up another
2351 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132352 handle_b[0].socket()->Disconnect();
2353 handle_b[0].Reset();
2354 handle_a[0].socket()->Disconnect();
2355 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542356
2357 // Used to get stuck here.
[email protected]b4c62eb2012-11-14 18:36:512358 MessageLoop::current()->RunUntilIdle();
[email protected]d7027bb2010-05-10 18:58:542359
[email protected]2431756e2010-09-29 20:26:132360 handle_b[1].socket()->Disconnect();
2361 handle_b[1].Reset();
2362 handle_a[1].socket()->Disconnect();
2363 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542364
2365 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132366 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2367 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542368 }
2369}
2370
[email protected]fd4fe0b2010-02-08 23:02:152371TEST_F(ClientSocketPoolBaseTest,
2372 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2373 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2374
2375 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2376
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 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2381
[email protected]2431756e2010-09-29 20:26:132382 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2383 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2384 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152385
2386 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132387 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2388 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152389
[email protected]2431756e2010-09-29 20:26:132390 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2391 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2392 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152393
2394 EXPECT_EQ(1, GetOrderOfRequest(1));
2395 EXPECT_EQ(2, GetOrderOfRequest(2));
2396 EXPECT_EQ(3, GetOrderOfRequest(3));
2397 EXPECT_EQ(4, GetOrderOfRequest(4));
2398
2399 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132400 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152401}
2402
[email protected]6ecf2b92011-12-15 01:14:522403class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042404 public:
[email protected]2431756e2010-09-29 20:26:132405 TestReleasingSocketRequest(TestClientSocketPool* pool,
2406 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182407 bool reset_releasing_handle)
2408 : pool_(pool),
2409 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522410 reset_releasing_handle_(reset_releasing_handle),
2411 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
2412 base::Bind(&TestReleasingSocketRequest::OnComplete,
2413 base::Unretained(this)))) {
2414 }
2415
2416 virtual ~TestReleasingSocketRequest() {}
[email protected]4f1e4982010-03-02 18:31:042417
2418 ClientSocketHandle* handle() { return &handle_; }
2419
[email protected]6ecf2b92011-12-15 01:14:522420 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042421
2422 private:
[email protected]6ecf2b92011-12-15 01:14:522423 void OnComplete(int result) {
2424 SetResult(result);
2425 if (reset_releasing_handle_)
2426 handle_.Reset();
2427
2428 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
2429 EXPECT_EQ(expected_result_,
2430 handle2_.Init("a", con_params, kDefaultPriority,
2431 callback2_.callback(), pool_, BoundNetLog()));
2432 }
2433
[email protected]2431756e2010-09-29 20:26:132434 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182435 int expected_result_;
2436 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042437 ClientSocketHandle handle_;
2438 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522439 CompletionCallback callback_;
2440 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042441};
2442
[email protected]e60e47a2010-07-14 03:37:182443
2444TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2445 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2446
2447 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2448 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2449 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2450
[email protected]2431756e2010-09-29 20:26:132451 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182452 client_socket_factory_.allocation_count());
2453
2454 connect_job_factory_->set_job_type(
2455 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2456 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132457 EXPECT_EQ(ERR_IO_PENDING,
[email protected]6ecf2b92011-12-15 01:14:522458 req.handle()->Init("a", params_, kDefaultPriority, req.callback(),
2459 pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182460 // The next job should complete synchronously
2461 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2462
2463 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2464 EXPECT_FALSE(req.handle()->is_initialized());
2465 EXPECT_FALSE(req.handle()->socket());
2466 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432467 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182468}
2469
[email protected]b6501d3d2010-06-03 23:53:342470// http://crbug.com/44724 regression test.
2471// We start releasing the pool when we flush on network change. When that
2472// happens, the only active references are in the ClientSocketHandles. When a
2473// ConnectJob completes and calls back into the last ClientSocketHandle, that
2474// callback can release the last reference and delete the pool. After the
2475// callback finishes, we go back to the stack frame within the now-deleted pool.
2476// Executing any code that refers to members of the now-deleted pool can cause
2477// crashes.
2478TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2479 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2480 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2481
2482 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522483 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132484 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2485 params_,
2486 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522487 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132488 pool_.get(),
2489 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342490
[email protected]7af985a2012-12-14 22:40:422491 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]b6501d3d2010-06-03 23:53:342492
2493 // We'll call back into this now.
2494 callback.WaitForResult();
2495}
2496
[email protected]a7e38572010-06-07 18:22:242497TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2498 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2499 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2500
2501 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522502 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132503 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2504 params_,
2505 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522506 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132507 pool_.get(),
2508 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242509 EXPECT_EQ(OK, callback.WaitForResult());
2510 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2511
[email protected]7af985a2012-12-14 22:40:422512 pool_->FlushWithError(ERR_NETWORK_CHANGED);
[email protected]a7e38572010-06-07 18:22:242513
2514 handle.Reset();
[email protected]b4c62eb2012-11-14 18:36:512515 MessageLoop::current()->RunUntilIdle();
[email protected]a7e38572010-06-07 18:22:242516
[email protected]2431756e2010-09-29 20:26:132517 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2518 params_,
2519 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522520 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132521 pool_.get(),
2522 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242523 EXPECT_EQ(OK, callback.WaitForResult());
2524 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2525}
2526
[email protected]6ecf2b92011-12-15 01:14:522527class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142528 public:
2529 ConnectWithinCallback(
2530 const std::string& group_name,
2531 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132532 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522533 : group_name_(group_name),
2534 params_(params),
2535 pool_(pool),
2536 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
2537 base::Bind(&ConnectWithinCallback::OnComplete,
2538 base::Unretained(this)))) {
[email protected]06f92462010-08-31 19:24:142539 }
2540
[email protected]6ecf2b92011-12-15 01:14:522541 virtual ~ConnectWithinCallback() {}
[email protected]06f92462010-08-31 19:24:142542
2543 int WaitForNestedResult() {
2544 return nested_callback_.WaitForResult();
2545 }
2546
[email protected]6ecf2b92011-12-15 01:14:522547 const CompletionCallback& callback() const { return callback_; }
2548
[email protected]06f92462010-08-31 19:24:142549 private:
[email protected]6ecf2b92011-12-15 01:14:522550 void OnComplete(int result) {
2551 SetResult(result);
2552 EXPECT_EQ(ERR_IO_PENDING,
2553 handle_.Init(group_name_,
2554 params_,
2555 kDefaultPriority,
2556 nested_callback_.callback(),
2557 pool_,
2558 BoundNetLog()));
2559 }
2560
[email protected]06f92462010-08-31 19:24:142561 const std::string group_name_;
2562 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132563 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142564 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522565 CompletionCallback callback_;
2566 TestCompletionCallback nested_callback_;
2567
2568 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142569};
2570
2571TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2572 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2573
2574 // First job will be waiting until it gets aborted.
2575 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2576
2577 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132578 ConnectWithinCallback callback("a", params_, pool_.get());
2579 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2580 params_,
2581 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522582 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132583 pool_.get(),
2584 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142585
2586 // Second job will be started during the first callback, and will
2587 // asynchronously complete with OK.
2588 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]7af985a2012-12-14 22:40:422589 pool_->FlushWithError(ERR_NETWORK_CHANGED);
2590 EXPECT_EQ(ERR_NETWORK_CHANGED, callback.WaitForResult());
[email protected]06f92462010-08-31 19:24:142591 EXPECT_EQ(OK, callback.WaitForNestedResult());
2592}
2593
[email protected]25eea382010-07-10 23:55:262594// Cancel a pending socket request while we're at max sockets,
2595// and verify that the backup socket firing doesn't cause a crash.
2596TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2597 // Max 4 sockets globally, max 4 sockets per group.
2598 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222599 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262600
[email protected]4baaf9d2010-08-31 15:15:442601 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2602 // timer.
[email protected]25eea382010-07-10 23:55:262603 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2604 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522605 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132606 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2607 params_,
2608 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522609 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132610 pool_.get(),
2611 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262612
2613 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2614 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2615 ClientSocketHandle handles[kDefaultMaxSockets];
2616 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522617 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132618 EXPECT_EQ(OK, handles[i].Init("bar",
2619 params_,
2620 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522621 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132622 pool_.get(),
2623 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262624 }
2625
[email protected]b4c62eb2012-11-14 18:36:512626 MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262627
2628 // Cancel the pending request.
2629 handle.Reset();
2630
2631 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002632 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2633 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262634
[email protected]b4c62eb2012-11-14 18:36:512635 MessageLoop::current()->RunUntilIdle();
[email protected]25eea382010-07-10 23:55:262636 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2637}
2638
[email protected]3f00be82010-09-27 19:50:022639TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442640 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2641 pool_->EnableConnectBackupJobs();
2642
2643 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2644 // timer.
2645 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2646 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522647 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132648 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2649 params_,
2650 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522651 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132652 pool_.get(),
2653 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442654 ASSERT_TRUE(pool_->HasGroup("bar"));
2655 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102656 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442657
2658 // Cancel the socket request. This should cancel the backup timer. Wait for
2659 // the backup time to see if it indeed got canceled.
2660 handle.Reset();
2661 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002662 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2663 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]b4c62eb2012-11-14 18:36:512664 MessageLoop::current()->RunUntilIdle();
[email protected]4baaf9d2010-08-31 15:15:442665 ASSERT_TRUE(pool_->HasGroup("bar"));
2666 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2667}
2668
[email protected]3f00be82010-09-27 19:50:022669TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2670 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2671 pool_->EnableConnectBackupJobs();
2672
2673 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2674 // timer.
2675 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2676 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522677 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132678 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2679 params_,
2680 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522681 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132682 pool_.get(),
2683 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022684 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2685 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522686 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132687 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2688 params_,
2689 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522690 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132691 pool_.get(),
2692 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022693 ASSERT_TRUE(pool_->HasGroup("bar"));
2694 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2695
2696 // Cancel request 1 and then complete request 2. With the requests finished,
2697 // the backup timer should be cancelled.
2698 handle.Reset();
2699 EXPECT_EQ(OK, callback2.WaitForResult());
2700 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002701 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2702 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]b4c62eb2012-11-14 18:36:512703 MessageLoop::current()->RunUntilIdle();
[email protected]3f00be82010-09-27 19:50:022704}
2705
[email protected]eb5a99382010-07-11 03:18:262706// Test delayed socket binding for the case where we have two connects,
2707// and while one is waiting on a connect, the other frees up.
2708// The socket waiting on a connect should switch immediately to the freed
2709// up socket.
2710TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2711 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2712 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2713
2714 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522715 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132716 EXPECT_EQ(ERR_IO_PENDING,
2717 handle1.Init("a",
2718 params_,
2719 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522720 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132721 pool_.get(),
2722 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262723 EXPECT_EQ(OK, callback.WaitForResult());
2724
2725 // No idle sockets, no pending jobs.
2726 EXPECT_EQ(0, pool_->IdleSocketCount());
2727 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2728
2729 // Create a second socket to the same host, but this one will wait.
2730 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2731 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132732 EXPECT_EQ(ERR_IO_PENDING,
2733 handle2.Init("a",
2734 params_,
2735 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522736 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132737 pool_.get(),
2738 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262739 // No idle sockets, and one connecting job.
2740 EXPECT_EQ(0, pool_->IdleSocketCount());
2741 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2742
2743 // Return the first handle to the pool. This will initiate the delayed
2744 // binding.
2745 handle1.Reset();
2746
[email protected]b4c62eb2012-11-14 18:36:512747 MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262748
2749 // Still no idle sockets, still one pending connect job.
2750 EXPECT_EQ(0, pool_->IdleSocketCount());
2751 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2752
2753 // The second socket connected, even though it was a Waiting Job.
2754 EXPECT_EQ(OK, callback.WaitForResult());
2755
2756 // And we can see there is still one job waiting.
2757 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2758
2759 // Finally, signal the waiting Connect.
2760 client_socket_factory_.SignalJobs();
2761 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2762
[email protected]b4c62eb2012-11-14 18:36:512763 MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262764}
2765
2766// Test delayed socket binding when a group is at capacity and one
2767// of the group's sockets frees up.
2768TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2769 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2770 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2771
2772 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522773 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132774 EXPECT_EQ(ERR_IO_PENDING,
2775 handle1.Init("a",
2776 params_,
2777 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522778 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132779 pool_.get(),
2780 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262781 EXPECT_EQ(OK, callback.WaitForResult());
2782
2783 // No idle sockets, no pending jobs.
2784 EXPECT_EQ(0, pool_->IdleSocketCount());
2785 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2786
2787 // Create a second socket to the same host, but this one will wait.
2788 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2789 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132790 EXPECT_EQ(ERR_IO_PENDING,
2791 handle2.Init("a",
2792 params_,
2793 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522794 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132795 pool_.get(),
2796 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262797 // No idle sockets, and one connecting job.
2798 EXPECT_EQ(0, pool_->IdleSocketCount());
2799 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2800
2801 // Return the first handle to the pool. This will initiate the delayed
2802 // binding.
2803 handle1.Reset();
2804
[email protected]b4c62eb2012-11-14 18:36:512805 MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262806
2807 // Still no idle sockets, still one pending connect job.
2808 EXPECT_EQ(0, pool_->IdleSocketCount());
2809 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2810
2811 // The second socket connected, even though it was a Waiting Job.
2812 EXPECT_EQ(OK, callback.WaitForResult());
2813
2814 // And we can see there is still one job waiting.
2815 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2816
2817 // Finally, signal the waiting Connect.
2818 client_socket_factory_.SignalJobs();
2819 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2820
[email protected]b4c62eb2012-11-14 18:36:512821 MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262822}
2823
2824// Test out the case where we have one socket connected, one
2825// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512826// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262827// should complete, by taking the first socket's idle socket.
2828TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2829 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2830 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2831
2832 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522833 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132834 EXPECT_EQ(ERR_IO_PENDING,
2835 handle1.Init("a",
2836 params_,
2837 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522838 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132839 pool_.get(),
2840 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262841 EXPECT_EQ(OK, callback.WaitForResult());
2842
2843 // No idle sockets, no pending jobs.
2844 EXPECT_EQ(0, pool_->IdleSocketCount());
2845 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2846
2847 // Create a second socket to the same host, but this one will wait.
2848 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2849 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132850 EXPECT_EQ(ERR_IO_PENDING,
2851 handle2.Init("a",
2852 params_,
2853 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522854 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132855 pool_.get(),
2856 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262857 // No idle sockets, and one connecting job.
2858 EXPECT_EQ(0, pool_->IdleSocketCount());
2859 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2860
2861 // Return the first handle to the pool. This will initiate the delayed
2862 // binding.
2863 handle1.Reset();
2864
[email protected]b4c62eb2012-11-14 18:36:512865 MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262866
2867 // Still no idle sockets, still one pending connect job.
2868 EXPECT_EQ(0, pool_->IdleSocketCount());
2869 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2870
2871 // The second socket connected, even though it was a Waiting Job.
2872 EXPECT_EQ(OK, callback.WaitForResult());
2873
2874 // And we can see there is still one job waiting.
2875 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2876
2877 // Finally, signal the waiting Connect.
2878 client_socket_factory_.SignalJobs();
2879 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2880
[email protected]b4c62eb2012-11-14 18:36:512881 MessageLoop::current()->RunUntilIdle();
[email protected]eb5a99382010-07-11 03:18:262882}
2883
[email protected]2abfe90a2010-08-25 17:49:512884// Cover the case where on an available socket slot, we have one pending
2885// request that completes synchronously, thereby making the Group empty.
2886TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2887 const int kUnlimitedSockets = 100;
2888 const int kOneSocketPerGroup = 1;
2889 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2890
2891 // Make the first request asynchronous fail.
2892 // This will free up a socket slot later.
2893 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2894
2895 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522896 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132897 EXPECT_EQ(ERR_IO_PENDING,
2898 handle1.Init("a",
2899 params_,
2900 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522901 callback1.callback(),
[email protected]2431756e2010-09-29 20:26:132902 pool_.get(),
2903 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512904 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2905
2906 // Make the second request synchronously fail. This should make the Group
2907 // empty.
2908 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2909 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522910 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:512911 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2912 // when created.
[email protected]2431756e2010-09-29 20:26:132913 EXPECT_EQ(ERR_IO_PENDING,
2914 handle2.Init("a",
2915 params_,
2916 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522917 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132918 pool_.get(),
2919 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512920
2921 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2922
2923 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2924 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2925 EXPECT_FALSE(pool_->HasGroup("a"));
2926}
2927
[email protected]e1b54dc2010-10-06 21:27:222928TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2929 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2930
2931 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2932
2933 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522934 TestCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:222935 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2936 params_,
2937 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522938 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:222939 pool_.get(),
2940 BoundNetLog()));
2941
2942 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522943 TestCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:222944 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2945 params_,
2946 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522947 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:222948 pool_.get(),
2949 BoundNetLog()));
2950 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522951 TestCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:222952 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2953 params_,
2954 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522955 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:222956 pool_.get(),
2957 BoundNetLog()));
2958
2959 EXPECT_EQ(OK, callback1.WaitForResult());
2960 EXPECT_EQ(OK, callback2.WaitForResult());
2961 EXPECT_EQ(OK, callback3.WaitForResult());
2962
2963 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552964 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
2965 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:222966
2967 handle1.Reset();
2968 handle2.Reset();
2969 handle3.Reset();
2970
2971 EXPECT_EQ(OK, handle1.Init("a",
2972 params_,
2973 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522974 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:222975 pool_.get(),
2976 BoundNetLog()));
2977 EXPECT_EQ(OK, handle2.Init("a",
2978 params_,
2979 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522980 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:222981 pool_.get(),
2982 BoundNetLog()));
2983 EXPECT_EQ(OK, handle3.Init("a",
2984 params_,
2985 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522986 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:222987 pool_.get(),
2988 BoundNetLog()));
2989
2990 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2991 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2992 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2993}
2994
[email protected]2c2bef152010-10-13 00:55:032995TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2996 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2997 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2998
2999 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3000
3001 ASSERT_TRUE(pool_->HasGroup("a"));
3002 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103003 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033004 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3005
3006 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523007 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033008 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3009 params_,
3010 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523011 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033012 pool_.get(),
3013 BoundNetLog()));
3014
3015 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523016 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033017 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3018 params_,
3019 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523020 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033021 pool_.get(),
3022 BoundNetLog()));
3023
3024 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103025 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033026 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3027
3028 EXPECT_EQ(OK, callback1.WaitForResult());
3029 EXPECT_EQ(OK, callback2.WaitForResult());
3030 handle1.Reset();
3031 handle2.Reset();
3032
3033 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103034 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033035 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3036}
3037
3038TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3039 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3040 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3041
3042 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523043 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033044 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3045 params_,
3046 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523047 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033048 pool_.get(),
3049 BoundNetLog()));
3050
3051 ASSERT_TRUE(pool_->HasGroup("a"));
3052 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103053 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033054 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3055
3056 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3057
3058 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103059 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033060 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3061
3062 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523063 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033064 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3065 params_,
3066 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523067 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033068 pool_.get(),
3069 BoundNetLog()));
3070
3071 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103072 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033073 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3074
3075 EXPECT_EQ(OK, callback1.WaitForResult());
3076 EXPECT_EQ(OK, callback2.WaitForResult());
3077 handle1.Reset();
3078 handle2.Reset();
3079
3080 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103081 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033082 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3083}
3084
3085TEST_F(ClientSocketPoolBaseTest,
3086 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3087 CreatePool(4, 4);
3088 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3089
3090 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523091 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033092 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3093 params_,
3094 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523095 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033096 pool_.get(),
3097 BoundNetLog()));
3098
3099 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523100 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033101 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3102 params_,
3103 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523104 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033105 pool_.get(),
3106 BoundNetLog()));
3107
3108 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523109 TestCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:033110 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3111 params_,
3112 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523113 callback3.callback(),
[email protected]2c2bef152010-10-13 00:55:033114 pool_.get(),
3115 BoundNetLog()));
3116
3117 ASSERT_TRUE(pool_->HasGroup("a"));
3118 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103119 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033120 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3121
3122 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3123
3124 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103125 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033126 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3127
3128 EXPECT_EQ(OK, callback1.WaitForResult());
3129 EXPECT_EQ(OK, callback2.WaitForResult());
3130 EXPECT_EQ(OK, callback3.WaitForResult());
3131 handle1.Reset();
3132 handle2.Reset();
3133 handle3.Reset();
3134
3135 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103136 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033137 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3138}
3139
3140TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3141 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3142 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3143
3144 ASSERT_FALSE(pool_->HasGroup("a"));
3145
3146 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3147 BoundNetLog());
3148
3149 ASSERT_TRUE(pool_->HasGroup("a"));
3150 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103151 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033152
3153 ASSERT_FALSE(pool_->HasGroup("b"));
3154
3155 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3156 BoundNetLog());
3157
3158 ASSERT_FALSE(pool_->HasGroup("b"));
3159}
3160
3161TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3162 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3163 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3164
3165 ASSERT_FALSE(pool_->HasGroup("a"));
3166
3167 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3168 BoundNetLog());
3169
3170 ASSERT_TRUE(pool_->HasGroup("a"));
3171 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103172 EXPECT_EQ(kDefaultMaxSockets - 1,
3173 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483174 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033175
3176 ASSERT_FALSE(pool_->HasGroup("b"));
3177
3178 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3179 BoundNetLog());
3180
3181 ASSERT_TRUE(pool_->HasGroup("b"));
3182 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483183 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033184}
3185
3186TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3187 CreatePool(4, 4);
3188 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3189
3190 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523191 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033192 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3193 params_,
3194 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523195 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033196 pool_.get(),
3197 BoundNetLog()));
3198 ASSERT_EQ(OK, callback1.WaitForResult());
3199 handle1.Reset();
3200
3201 ASSERT_TRUE(pool_->HasGroup("a"));
3202 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103203 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033204 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3205
3206 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3207
3208 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103209 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033210 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3211}
3212
3213TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3214 CreatePool(4, 4);
3215 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3216
3217 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523218 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033219 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3220 params_,
3221 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523222 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033223 pool_.get(),
3224 BoundNetLog()));
3225 ASSERT_EQ(OK, callback1.WaitForResult());
3226
3227 ASSERT_TRUE(pool_->HasGroup("a"));
3228 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103229 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033230 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3231 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3232
3233 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3234
3235 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103236 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033237 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3238 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3239}
3240
3241TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3242 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3243 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3244
3245 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3246 BoundNetLog());
3247
3248 ASSERT_TRUE(pool_->HasGroup("a"));
3249 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103250 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033251 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3252
3253 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3254 BoundNetLog());
3255
3256 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103257 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033258 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3259}
3260
[email protected]3c819f522010-12-02 02:03:123261TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3262 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3263 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3264
3265 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3266 BoundNetLog());
3267
3268 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523269
3270 connect_job_factory_->set_job_type(
3271 TestConnectJob::kMockAdditionalErrorStateJob);
3272 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3273 BoundNetLog());
3274
3275 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123276}
3277
[email protected]8159a1c2012-06-07 00:00:103278TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033279 CreatePool(4, 4);
3280 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3281
3282 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3283
3284 ASSERT_TRUE(pool_->HasGroup("a"));
3285 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103286 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033287 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3288
3289 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3290 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103291 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033292 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3293
3294 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523295 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033296 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3297 params_,
3298 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523299 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033300 pool_.get(),
3301 BoundNetLog()));
3302 ASSERT_EQ(OK, callback1.WaitForResult());
3303
3304 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523305 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033306 int rv = handle2.Init("a",
3307 params_,
3308 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523309 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033310 pool_.get(),
3311 BoundNetLog());
3312 if (rv != OK) {
3313 EXPECT_EQ(ERR_IO_PENDING, rv);
3314 EXPECT_EQ(OK, callback2.WaitForResult());
3315 }
3316
[email protected]8159a1c2012-06-07 00:00:103317 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3318 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3319 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3320 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3321
[email protected]2c2bef152010-10-13 00:55:033322 handle1.Reset();
3323 handle2.Reset();
3324
[email protected]8159a1c2012-06-07 00:00:103325 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3326 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033327 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3328
3329 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3330 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103331 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033332 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3333}
3334
3335TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3336 CreatePool(4, 4);
3337 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3338
3339 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3340
3341 ASSERT_TRUE(pool_->HasGroup("a"));
3342 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103343 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033344 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3345
3346 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3347 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103348 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033349 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3350
3351 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3352 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103353 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033354 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3355
3356 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3357 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103358 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033359 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3360}
3361
3362TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3363 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3364 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3365
3366 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3367
3368 ASSERT_TRUE(pool_->HasGroup("a"));
3369 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103370 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033371 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3372
3373 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523374 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033375 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3376 params_,
3377 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523378 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033379 pool_.get(),
3380 BoundNetLog()));
3381
3382 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103383 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033384 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3385
3386 ASSERT_EQ(OK, callback1.WaitForResult());
3387
[email protected]034df0f32013-01-07 23:17:483388 // Make sure if a preconneced socket is not fully connected when a request
3389 // starts, it has a connect start time.
3390 TestLoadTimingInfoConnectedNotReused(handle1);
[email protected]2c2bef152010-10-13 00:55:033391 handle1.Reset();
3392
3393 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3394}
3395
[email protected]034df0f32013-01-07 23:17:483396// Checks that fully connected preconnect jobs have no connect times, and are
3397// marked as reused.
3398TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
3399 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3400 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3401 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3402
3403 ASSERT_TRUE(pool_->HasGroup("a"));
3404 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3405 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3406 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3407
3408 ClientSocketHandle handle;
3409 TestCompletionCallback callback;
3410 EXPECT_EQ(OK, handle.Init("a",
3411 params_,
3412 kDefaultPriority,
3413 callback.callback(),
3414 pool_.get(),
3415 BoundNetLog()));
3416
3417 // Make sure the idle socket was used.
3418 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3419
3420 TestLoadTimingInfoConnectedReused(handle);
3421 handle.Reset();
3422 TestLoadTimingInfoNotConnected(handle);
3423}
3424
[email protected]dcbe168a2010-12-02 03:14:463425// http://crbug.com/64940 regression test.
3426TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3427 const int kMaxTotalSockets = 3;
3428 const int kMaxSocketsPerGroup = 2;
3429 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3430 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3431
3432 // Note that group name ordering matters here. "a" comes before "b", so
3433 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3434
3435 // Set up one idle socket in "a".
3436 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523437 TestCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463438 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3439 params_,
3440 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523441 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463442 pool_.get(),
3443 BoundNetLog()));
3444
3445 ASSERT_EQ(OK, callback1.WaitForResult());
3446 handle1.Reset();
3447 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3448
3449 // Set up two active sockets in "b".
3450 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523451 TestCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463452 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3453 params_,
3454 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523455 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463456 pool_.get(),
3457 BoundNetLog()));
3458 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3459 params_,
3460 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523461 callback2.callback(),
[email protected]dcbe168a2010-12-02 03:14:463462 pool_.get(),
3463 BoundNetLog()));
3464
3465 ASSERT_EQ(OK, callback1.WaitForResult());
3466 ASSERT_EQ(OK, callback2.WaitForResult());
3467 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103468 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463469 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3470
3471 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3472 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3473 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3474 // sockets for "a", and "b" should still have 2 active sockets.
3475
3476 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3477 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103478 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463479 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3480 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3481 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103482 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463483 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3484 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3485
3486 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3487 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3488 // "a" should result in closing 1 for "b".
3489 handle1.Reset();
3490 handle2.Reset();
3491 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3492 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3493
3494 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3495 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103496 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463497 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3498 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3499 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103500 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463501 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3502 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3503}
3504
[email protected]b7b8be42011-07-12 12:46:413505TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073506 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3507 pool_->EnableConnectBackupJobs();
3508
3509 // Make the ConnectJob hang until it times out, shorten the timeout.
3510 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3511 connect_job_factory_->set_timeout_duration(
3512 base::TimeDelta::FromMilliseconds(500));
3513 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3514 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103515 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073516 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073517
[email protected]b7b8be42011-07-12 12:46:413518 // Verify the backup timer doesn't create a backup job, by making
3519 // the backup job a pending job instead of a waiting job, so it
3520 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073521 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5761ab9c2012-02-04 16:44:533522 MessageLoop::current()->PostDelayedTask(
3523 FROM_HERE, MessageLoop::QuitClosure(), base::TimeDelta::FromSeconds(1));
[email protected]b7b8be42011-07-12 12:46:413524 MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073525 EXPECT_FALSE(pool_->HasGroup("a"));
3526}
3527
[email protected]b7b8be42011-07-12 12:46:413528TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073529 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3530 pool_->EnableConnectBackupJobs();
3531
3532 // Make the ConnectJob hang forever.
3533 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3534 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3535 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103536 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073537 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]b4c62eb2012-11-14 18:36:513538 MessageLoop::current()->RunUntilIdle();
[email protected]a9fc8fc2011-05-10 02:41:073539
3540 // Make the backup job be a pending job, so it completes normally.
3541 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3542 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523543 TestCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073544 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3545 params_,
3546 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523547 callback.callback(),
[email protected]a9fc8fc2011-05-10 02:41:073548 pool_.get(),
3549 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413550 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073551 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103552 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073553 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3554 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3555 ASSERT_EQ(OK, callback.WaitForResult());
3556
3557 // The hung connect job should still be there, but everything else should be
3558 // complete.
3559 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103560 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073561 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3562 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3563}
3564
[email protected]f6d1d6eb2009-06-24 20:16:093565} // namespace
3566
3567} // namespace net