blob: b1961689ba11565d3303a85b5515e6d178151942 [file] [log] [blame]
[email protected]7fc5b09a2010-02-27 00:07:381// Copyright (c) 2010 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]2041cf342010-02-19 03:15:597#include "base/callback.h"
[email protected]f6d1d6eb2009-06-24 20:16:098#include "base/compiler_specific.h"
9#include "base/message_loop.h"
[email protected]974ebd62009-08-03 23:14:3410#include "base/platform_thread.h"
[email protected]df4b4ef2010-07-12 18:25:2111#include "base/ref_counted.h"
[email protected]c9d6a1d2009-07-14 16:15:2012#include "base/scoped_vector.h"
[email protected]e83326f2010-07-31 17:29:2513#include "base/string_number_conversions.h"
[email protected]43a21b82010-06-10 21:30:5414#include "base/string_util.h"
[email protected]9e743cd2010-03-16 07:03:5315#include "net/base/net_log.h"
16#include "net/base/net_log_unittest.h"
[email protected]f6d1d6eb2009-06-24 20:16:0917#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3118#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0919#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3520#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0921#include "net/socket/client_socket.h"
22#include "net/socket/client_socket_factory.h"
23#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0024#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1725#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0926#include "testing/gtest/include/gtest/gtest.h"
27
28namespace net {
29
30namespace {
31
[email protected]211d21722009-07-22 15:48:5332const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2033const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5234const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0135
[email protected]df4b4ef2010-07-12 18:25:2136class TestSocketParams : public base::RefCounted<TestSocketParams> {
37 private:
38 friend class base::RefCounted<TestSocketParams>;
39 ~TestSocketParams() {}
40};
[email protected]7fc5b09a2010-02-27 00:07:3841typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4942
[email protected]f6d1d6eb2009-06-24 20:16:0943class MockClientSocket : public ClientSocket {
44 public:
[email protected]0f873e82010-09-02 16:09:0145 MockClientSocket() : connected_(false), was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:0946
[email protected]ab838892009-06-30 18:49:0547 // Socket methods:
48 virtual int Read(
49 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
50 return ERR_UNEXPECTED;
51 }
52
53 virtual int Write(
[email protected]0f873e82010-09-02 16:09:0154 IOBuffer* /* buf */, int len, CompletionCallback* /* callback */) {
55 was_used_to_convey_data_ = true;
56 return len;
[email protected]ab838892009-06-30 18:49:0557 }
[email protected]06650c52010-06-03 00:49:1758 virtual bool SetReceiveBufferSize(int32 size) { return true; }
59 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0560
[email protected]f6d1d6eb2009-06-24 20:16:0961 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0562
[email protected]a2006ece2010-04-23 16:44:0263 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0964 connected_ = true;
65 return OK;
66 }
[email protected]f6d1d6eb2009-06-24 20:16:0967
[email protected]ab838892009-06-30 18:49:0568 virtual void Disconnect() { connected_ = false; }
69 virtual bool IsConnected() const { return connected_; }
70 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0171
[email protected]ac9eec62010-02-20 18:50:3872 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1673 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0974 }
[email protected]f6d1d6eb2009-06-24 20:16:0975
[email protected]a2006ece2010-04-23 16:44:0276 virtual const BoundNetLog& NetLog() const {
77 return net_log_;
78 }
79
[email protected]9b5614a2010-08-25 20:29:4580 virtual void SetSubresourceSpeculation() {}
81 virtual void SetOmniboxSpeculation() {}
[email protected]0f873e82010-09-02 16:09:0182 virtual bool WasEverUsed() const { return was_used_to_convey_data_; }
[email protected]9b5614a2010-08-25 20:29:4583
[email protected]f6d1d6eb2009-06-24 20:16:0984 private:
85 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0286 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:0187 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:0988
[email protected]ab838892009-06-30 18:49:0589 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0990};
91
[email protected]5fc08e32009-07-15 17:09:5792class TestConnectJob;
93
[email protected]f6d1d6eb2009-06-24 20:16:0994class MockClientSocketFactory : public ClientSocketFactory {
95 public:
[email protected]ab838892009-06-30 18:49:0596 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0997
[email protected]0a0b7682010-08-25 17:08:0798 virtual ClientSocket* CreateTCPClientSocket(
99 const AddressList& addresses,
100 NetLog* /* net_log */,
101 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09102 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05103 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09104 }
105
106 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18107 ClientSocketHandle* transport_socket,
[email protected]f6d1d6eb2009-06-24 20:16:09108 const std::string& hostname,
109 const SSLConfig& ssl_config) {
110 NOTIMPLEMENTED();
111 return NULL;
112 }
113
[email protected]5fc08e32009-07-15 17:09:57114 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
115 void SignalJobs();
116
[email protected]f6d1d6eb2009-06-24 20:16:09117 int allocation_count() const { return allocation_count_; }
118
[email protected]f6d1d6eb2009-06-24 20:16:09119 private:
120 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57121 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09122};
123
[email protected]ab838892009-06-30 18:49:05124class TestConnectJob : public ConnectJob {
125 public:
126 enum JobType {
127 kMockJob,
128 kMockFailingJob,
129 kMockPendingJob,
130 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57131 kMockWaitingJob,
132 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13133 kMockRecoverableJob,
134 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18135 kMockAdditionalErrorStateJob,
136 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05137 };
138
[email protected]994d4932010-07-12 17:55:13139 // The kMockPendingJob uses a slight delay before allowing the connect
140 // to complete.
141 static const int kPendingConnectDelay = 2;
142
[email protected]ab838892009-06-30 18:49:05143 TestConnectJob(JobType job_type,
144 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49145 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34146 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05147 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30148 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17149 NetLog* net_log)
150 : ConnectJob(group_name, timeout_duration, delegate,
151 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58152 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05153 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21154 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18155 load_state_(LOAD_STATE_IDLE),
156 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05157
[email protected]974ebd62009-08-03 23:14:34158 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13159 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34160 }
161
[email protected]46451352009-09-01 14:54:21162 virtual LoadState GetLoadState() const { return load_state_; }
163
[email protected]e60e47a2010-07-14 03:37:18164 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
165 if (store_additional_error_state_) {
166 // Set all of the additional error state fields in some way.
167 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43168 HttpResponseInfo info;
169 info.headers = new HttpResponseHeaders("");
170 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18171 }
172 }
173
[email protected]974ebd62009-08-03 23:14:34174 private:
[email protected]ab838892009-06-30 18:49:05175 // ConnectJob methods:
176
[email protected]974ebd62009-08-03 23:14:34177 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05178 AddressList ignored;
[email protected]0a0b7682010-08-25 17:08:07179 client_socket_factory_->CreateTCPClientSocket(
180 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40181 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05182 switch (job_type_) {
183 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13184 return DoConnect(true /* successful */, false /* sync */,
185 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05186 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13187 return DoConnect(false /* error */, false /* sync */,
188 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05189 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57190 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47191
192 // Depending on execution timings, posting a delayed task can result
193 // in the task getting executed the at the earliest possible
194 // opportunity or only after returning once from the message loop and
195 // then a second call into the message loop. In order to make behavior
196 // more deterministic, we change the default delay to 2ms. This should
197 // always require us to wait for the second call into the message loop.
198 //
199 // N.B. The correct fix for this and similar timing problems is to
200 // abstract time for the purpose of unittests. Unfortunately, we have
201 // a lot of third-party components that directly call the various
202 // time functions, so this change would be rather invasive.
203 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05204 FROM_HERE,
205 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47206 &TestConnectJob::DoConnect,
207 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13208 true /* async */,
209 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13210 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05211 return ERR_IO_PENDING;
212 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57213 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47214 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05215 FROM_HERE,
216 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47217 &TestConnectJob::DoConnect,
218 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13219 true /* async */,
220 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47221 2);
[email protected]ab838892009-06-30 18:49:05222 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57223 case kMockWaitingJob:
224 client_socket_factory_->WaitForSignal(this);
225 waiting_success_ = true;
226 return ERR_IO_PENDING;
227 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46228 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57229 FROM_HERE,
230 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46231 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57232 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13233 case kMockRecoverableJob:
234 return DoConnect(false /* error */, false /* sync */,
235 true /* recoverable */);
236 case kMockPendingRecoverableJob:
237 set_load_state(LOAD_STATE_CONNECTING);
238 MessageLoop::current()->PostDelayedTask(
239 FROM_HERE,
240 method_factory_.NewRunnableMethod(
241 &TestConnectJob::DoConnect,
242 false /* error */,
243 true /* async */,
244 true /* recoverable */),
245 2);
246 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18247 case kMockAdditionalErrorStateJob:
248 store_additional_error_state_ = true;
249 return DoConnect(false /* error */, false /* sync */,
250 false /* recoverable */);
251 case kMockPendingAdditionalErrorStateJob:
252 set_load_state(LOAD_STATE_CONNECTING);
253 store_additional_error_state_ = true;
254 MessageLoop::current()->PostDelayedTask(
255 FROM_HERE,
256 method_factory_.NewRunnableMethod(
257 &TestConnectJob::DoConnect,
258 false /* error */,
259 true /* async */,
260 false /* recoverable */),
261 2);
262 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05263 default:
264 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40265 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05266 return ERR_FAILED;
267 }
268 }
269
[email protected]46451352009-09-01 14:54:21270 void set_load_state(LoadState load_state) { load_state_ = load_state; }
271
[email protected]e772db3f2010-07-12 18:11:13272 int DoConnect(bool succeed, bool was_async, bool recoverable) {
273 int result = OK;
[email protected]ab838892009-06-30 18:49:05274 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02275 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13276 } else if (recoverable) {
277 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40278 } else {
[email protected]e772db3f2010-07-12 18:11:13279 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40280 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05281 }
[email protected]2ab05b52009-07-01 23:57:58282
283 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30284 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05285 return result;
286 }
287
[email protected]cfa8228c2010-06-17 01:07:56288 // This function helps simulate the progress of load states on a ConnectJob.
289 // Each time it is called it advances the load state and posts a task to be
290 // called again. It stops at the last connecting load state (the one
291 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57292 void AdvanceLoadState(LoadState state) {
293 int tmp = state;
294 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56295 if (tmp < LOAD_STATE_SENDING_REQUEST) {
296 state = static_cast<LoadState>(tmp);
297 set_load_state(state);
298 MessageLoop::current()->PostTask(
299 FROM_HERE,
300 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
301 state));
302 }
[email protected]5fc08e32009-07-15 17:09:57303 }
304
305 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05306 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57307 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05308 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21309 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18310 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05311
312 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
313};
314
[email protected]d80a4322009-08-14 07:07:49315class TestConnectJobFactory
316 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05317 public:
[email protected]5fc08e32009-07-15 17:09:57318 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05319 : job_type_(TestConnectJob::kMockJob),
320 client_socket_factory_(client_socket_factory) {}
321
322 virtual ~TestConnectJobFactory() {}
323
324 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
325
[email protected]974ebd62009-08-03 23:14:34326 void set_timeout_duration(base::TimeDelta timeout_duration) {
327 timeout_duration_ = timeout_duration;
328 }
329
[email protected]ab838892009-06-30 18:49:05330 // ConnectJobFactory methods:
331
332 virtual ConnectJob* NewConnectJob(
333 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49334 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17335 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05336 return new TestConnectJob(job_type_,
337 group_name,
338 request,
[email protected]974ebd62009-08-03 23:14:34339 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05340 delegate,
[email protected]fd7b7c92009-08-20 19:38:30341 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17342 NULL);
[email protected]ab838892009-06-30 18:49:05343 }
344
[email protected]a796bcec2010-03-22 17:17:26345 virtual base::TimeDelta ConnectionTimeout() const {
346 return timeout_duration_;
347 }
348
[email protected]ab838892009-06-30 18:49:05349 private:
350 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34351 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57352 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05353
354 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
355};
356
357class TestClientSocketPool : public ClientSocketPool {
358 public:
359 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53360 int max_sockets,
[email protected]ab838892009-06-30 18:49:05361 int max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00362 const scoped_refptr<ClientSocketPoolHistograms>& histograms,
[email protected]9bf28db2009-08-29 01:35:16363 base::TimeDelta unused_idle_socket_timeout,
364 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49365 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00366 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16367 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38368 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05369
370 virtual int RequestSocket(
371 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49372 const void* params,
[email protected]ac790b42009-12-02 04:31:31373 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05374 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46375 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53376 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21377 const scoped_refptr<TestSocketParams>* casted_socket_params =
378 static_cast<const scoped_refptr<TestSocketParams>*>(params);
379 return base_.RequestSocket(group_name, *casted_socket_params, priority,
380 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05381 }
382
383 virtual void CancelRequest(
384 const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21385 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49386 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05387 }
388
389 virtual void ReleaseSocket(
390 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24391 ClientSocket* socket,
392 int id) {
393 base_.ReleaseSocket(group_name, socket, id);
394 }
395
396 virtual void Flush() {
397 base_.Flush();
[email protected]ab838892009-06-30 18:49:05398 }
399
400 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49401 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05402 }
403
[email protected]d80a4322009-08-14 07:07:49404 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05405
406 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49407 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05408 }
409
410 virtual LoadState GetLoadState(const std::string& group_name,
411 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49412 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05413 }
414
[email protected]59d7a5a2010-08-30 16:44:27415 virtual Value* GetInfoAsValue(const std::string& name,
416 const std::string& type) const {
417 return base_.GetInfoAsValue(name, type);
418 }
419
[email protected]a796bcec2010-03-22 17:17:26420 virtual base::TimeDelta ConnectionTimeout() const {
421 return base_.ConnectionTimeout();
422 }
423
[email protected]b89f7e42010-05-20 20:37:00424 virtual scoped_refptr<ClientSocketPoolHistograms> histograms() const {
425 return base_.histograms();
426 }
[email protected]a796bcec2010-03-22 17:17:26427
[email protected]d80a4322009-08-14 07:07:49428 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20429
[email protected]974ebd62009-08-03 23:14:34430 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49431 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34432 }
433
[email protected]2abfe90a2010-08-25 17:49:51434 bool HasGroup(const std::string& group_name) const {
435 return base_.HasGroup(group_name);
436 }
437
[email protected]9bf28db2009-08-29 01:35:16438 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
439
[email protected]06d94042010-08-25 01:45:22440 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54441
[email protected]ab838892009-06-30 18:49:05442 private:
[email protected]5389bc72009-11-05 23:34:24443 ~TestClientSocketPool() {}
444
[email protected]d80a4322009-08-14 07:07:49445 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05446
447 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
448};
449
[email protected]a937a06d2009-08-19 21:19:24450} // namespace
451
[email protected]7fc5b09a2010-02-27 00:07:38452REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24453
454namespace {
455
[email protected]5fc08e32009-07-15 17:09:57456void MockClientSocketFactory::SignalJobs() {
457 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
458 it != waiting_jobs_.end(); ++it) {
459 (*it)->Signal();
460 }
461 waiting_jobs_.clear();
462}
463
[email protected]974ebd62009-08-03 23:14:34464class TestConnectJobDelegate : public ConnectJob::Delegate {
465 public:
466 TestConnectJobDelegate()
467 : have_result_(false), waiting_for_result_(false), result_(OK) {}
468 virtual ~TestConnectJobDelegate() {}
469
470 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
471 result_ = result;
[email protected]6e713f02009-08-06 02:56:40472 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07473 // socket.get() should be NULL iff result != OK
474 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34475 delete job;
476 have_result_ = true;
477 if (waiting_for_result_)
478 MessageLoop::current()->Quit();
479 }
480
481 int WaitForResult() {
482 DCHECK(!waiting_for_result_);
483 while (!have_result_) {
484 waiting_for_result_ = true;
485 MessageLoop::current()->Run();
486 waiting_for_result_ = false;
487 }
488 have_result_ = false; // auto-reset for next callback
489 return result_;
490 }
491
492 private:
493 bool have_result_;
494 bool waiting_for_result_;
495 int result_;
496};
497
[email protected]75439d3b2009-07-23 22:11:17498class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09499 protected:
[email protected]b89f7e42010-05-20 20:37:00500 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21501 : params_(new TestSocketParams()),
502 histograms_(new ClientSocketPoolHistograms("ClientSocketPoolTest")) {}
[email protected]c9d6a1d2009-07-14 16:15:20503
[email protected]211d21722009-07-22 15:48:53504 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16505 CreatePoolWithIdleTimeouts(
506 max_sockets,
507 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00508 base::TimeDelta::FromSeconds(
509 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16510 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
511 }
512
513 void CreatePoolWithIdleTimeouts(
514 int max_sockets, int max_sockets_per_group,
515 base::TimeDelta unused_idle_socket_timeout,
516 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20517 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04518 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53519 pool_ = new TestClientSocketPool(max_sockets,
520 max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00521 histograms_,
[email protected]9bf28db2009-08-29 01:35:16522 unused_idle_socket_timeout,
523 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20524 connect_job_factory_);
525 }
[email protected]f6d1d6eb2009-06-24 20:16:09526
[email protected]ac790b42009-12-02 04:31:31527 int StartRequest(const std::string& group_name,
528 net::RequestPriority priority) {
[email protected]7fc5b09a2010-02-27 00:07:38529 return StartRequestUsingPool<TestClientSocketPool, TestSocketParams>(
[email protected]df4b4ef2010-07-12 18:25:21530 pool_, group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09531 }
532
533 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47534 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
535 // actually become pending until 2ms after they have been created. In order
536 // to flush all tasks, we need to wait so that we know there are no
537 // soon-to-be-pending tasks waiting.
538 PlatformThread::Sleep(10);
539 MessageLoop::current()->RunAllPending();
540
[email protected]211d21722009-07-22 15:48:53541 // Need to delete |pool_| before we turn late binding back off. We also need
542 // to delete |requests_| because the pool is reference counted and requests
543 // keep reference to it.
544 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]05ea9ff2010-07-15 19:08:21545 TestClientSocketPool* pool = pool_.get();
[email protected]5fc08e32009-07-15 17:09:57546 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53547 requests_.reset();
[email protected]05ea9ff2010-07-15 19:08:21548 pool = NULL;
[email protected]211d21722009-07-22 15:48:53549
[email protected]75439d3b2009-07-23 22:11:17550 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09551 }
552
[email protected]f6d1d6eb2009-06-24 20:16:09553 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04554 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21555 scoped_refptr<TestSocketParams> params_;
[email protected]c9d6a1d2009-07-14 16:15:20556 scoped_refptr<TestClientSocketPool> pool_;
[email protected]b89f7e42010-05-20 20:37:00557 scoped_refptr<ClientSocketPoolHistograms> histograms_;
[email protected]f6d1d6eb2009-06-24 20:16:09558};
559
[email protected]974ebd62009-08-03 23:14:34560// Even though a timeout is specified, it doesn't time out on a synchronous
561// completion.
562TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
563 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06564 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49565 TestClientSocketPoolBase::Request request(
[email protected]df4b4ef2010-07-12 18:25:21566 &ignored, NULL, kDefaultPriority, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34567 scoped_ptr<TestConnectJob> job(
568 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12569 "a",
[email protected]974ebd62009-08-03 23:14:34570 request,
571 base::TimeDelta::FromMicroseconds(1),
572 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30573 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17574 NULL));
[email protected]974ebd62009-08-03 23:14:34575 EXPECT_EQ(OK, job->Connect());
576}
577
578TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
579 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06580 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17581 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53582
[email protected]d80a4322009-08-14 07:07:49583 TestClientSocketPoolBase::Request request(
[email protected]df4b4ef2010-07-12 18:25:21584 &ignored, NULL, kDefaultPriority, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34585 // Deleted by TestConnectJobDelegate.
586 TestConnectJob* job =
587 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12588 "a",
[email protected]974ebd62009-08-03 23:14:34589 request,
590 base::TimeDelta::FromMicroseconds(1),
591 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30592 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17593 &log);
[email protected]974ebd62009-08-03 23:14:34594 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
595 PlatformThread::Sleep(1);
596 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30597
[email protected]06650c52010-06-03 00:49:17598 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46599 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53600 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17601 EXPECT_TRUE(LogContainsBeginEvent(
602 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46603 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17604 log.entries(), 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
605 NetLog::PHASE_NONE));
606 EXPECT_TRUE(LogContainsEvent(
607 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53608 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46609 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17610 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
611 EXPECT_TRUE(LogContainsEndEvent(
612 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34613}
614
[email protected]5fc08e32009-07-15 17:09:57615TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53616 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20617
[email protected]f6d1d6eb2009-06-24 20:16:09618 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06619 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53620 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
621
[email protected]df4b4ef2010-07-12 18:25:21622 EXPECT_EQ(OK, handle.Init("a", params_, kDefaultPriority, &callback, pool_,
623 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09624 EXPECT_TRUE(handle.is_initialized());
625 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09626 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30627
[email protected]06650c52010-06-03 00:49:17628 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46629 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53630 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53631 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17632 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
633 NetLog::PHASE_NONE));
634 EXPECT_TRUE(LogContainsEvent(
635 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53636 NetLog::PHASE_NONE));
637 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17638 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09639}
640
[email protected]ab838892009-06-30 18:49:05641TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53642 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20643
[email protected]ab838892009-06-30 18:49:05644 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53645 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
646
[email protected]a512f5982009-08-18 16:01:06647 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]e60e47a2010-07-14 03:37:18648 // Set the additional error state members to ensure that they get cleared.
649 req.handle()->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43650 HttpResponseInfo info;
651 info.headers = new HttpResponseHeaders("");
652 req.handle()->set_ssl_error_response_info(info);
[email protected]df4b4ef2010-07-12 18:25:21653 EXPECT_EQ(ERR_CONNECTION_FAILED, req.handle()->Init("a", params_,
654 kDefaultPriority, &req,
655 pool_, log.bound()));
[email protected]e772db3f2010-07-12 18:11:13656 EXPECT_FALSE(req.handle()->socket());
[email protected]e60e47a2010-07-14 03:37:18657 EXPECT_FALSE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:43658 EXPECT_TRUE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30659
[email protected]06650c52010-06-03 00:49:17660 EXPECT_EQ(3u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27661 EXPECT_TRUE(LogContainsBeginEvent(
662 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17663 EXPECT_TRUE(LogContainsEvent(
664 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
665 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02666 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17667 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09668}
669
[email protected]211d21722009-07-22 15:48:53670TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
671 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
672
[email protected]9e743cd2010-03-16 07:03:53673 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30674
[email protected]211d21722009-07-22 15:48:53675 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
676 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
677 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
678 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
679
680 EXPECT_EQ(static_cast<int>(requests_.size()),
681 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17682 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53683
684 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
685 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
686 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
687
[email protected]43a21b82010-06-10 21:30:54688 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53689
690 EXPECT_EQ(static_cast<int>(requests_.size()),
691 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17692 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53693
694 EXPECT_EQ(1, GetOrderOfRequest(1));
695 EXPECT_EQ(2, GetOrderOfRequest(2));
696 EXPECT_EQ(3, GetOrderOfRequest(3));
697 EXPECT_EQ(4, GetOrderOfRequest(4));
698 EXPECT_EQ(5, GetOrderOfRequest(5));
699 EXPECT_EQ(6, GetOrderOfRequest(6));
700 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17701
702 // Make sure we test order of all requests made.
703 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53704}
705
706TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
707 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
708
[email protected]9e743cd2010-03-16 07:03:53709 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30710
[email protected]211d21722009-07-22 15:48:53711 // Reach all limits: max total sockets, and max sockets per group.
712 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
713 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
714 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
715 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
716
717 EXPECT_EQ(static_cast<int>(requests_.size()),
718 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17719 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53720
721 // Now create a new group and verify that we don't starve it.
722 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
723
[email protected]43a21b82010-06-10 21:30:54724 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53725
726 EXPECT_EQ(static_cast<int>(requests_.size()),
727 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17728 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53729
730 EXPECT_EQ(1, GetOrderOfRequest(1));
731 EXPECT_EQ(2, GetOrderOfRequest(2));
732 EXPECT_EQ(3, GetOrderOfRequest(3));
733 EXPECT_EQ(4, GetOrderOfRequest(4));
734 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17735
736 // Make sure we test order of all requests made.
737 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53738}
739
740TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
741 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
742
[email protected]ac790b42009-12-02 04:31:31743 EXPECT_EQ(OK, StartRequest("b", LOWEST));
744 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
745 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
746 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53747
748 EXPECT_EQ(static_cast<int>(requests_.size()),
749 client_socket_factory_.allocation_count());
750
[email protected]ac790b42009-12-02 04:31:31751 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
752 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
753 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53754
[email protected]43a21b82010-06-10 21:30:54755 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53756
[email protected]75439d3b2009-07-23 22:11:17757 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53758
759 // First 4 requests don't have to wait, and finish in order.
760 EXPECT_EQ(1, GetOrderOfRequest(1));
761 EXPECT_EQ(2, GetOrderOfRequest(2));
762 EXPECT_EQ(3, GetOrderOfRequest(3));
763 EXPECT_EQ(4, GetOrderOfRequest(4));
764
[email protected]ac790b42009-12-02 04:31:31765 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
766 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53767 EXPECT_EQ(7, GetOrderOfRequest(5));
768 EXPECT_EQ(6, GetOrderOfRequest(6));
769 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17770
771 // Make sure we test order of all requests made.
[email protected]c9c6f5c2010-07-31 01:30:03772 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53773}
774
775TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
776 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
777
[email protected]ac790b42009-12-02 04:31:31778 EXPECT_EQ(OK, StartRequest("a", LOWEST));
779 EXPECT_EQ(OK, StartRequest("a", LOW));
780 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
781 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53782
783 EXPECT_EQ(static_cast<int>(requests_.size()),
784 client_socket_factory_.allocation_count());
785
[email protected]ac790b42009-12-02 04:31:31786 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
787 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
788 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53789
[email protected]43a21b82010-06-10 21:30:54790 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53791
[email protected]43a21b82010-06-10 21:30:54792 EXPECT_EQ(static_cast<int>(requests_.size()),
[email protected]211d21722009-07-22 15:48:53793 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17794 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53795
796 // First 4 requests don't have to wait, and finish in order.
797 EXPECT_EQ(1, GetOrderOfRequest(1));
798 EXPECT_EQ(2, GetOrderOfRequest(2));
799 EXPECT_EQ(3, GetOrderOfRequest(3));
800 EXPECT_EQ(4, GetOrderOfRequest(4));
801
802 // Request ("b", 7) has the highest priority, but we can't make new socket for
803 // group "b", because it has reached the per-group limit. Then we make
804 // socket for ("c", 6), because it has higher priority than ("a", 4),
805 // and we still can't make a socket for group "b".
806 EXPECT_EQ(5, GetOrderOfRequest(5));
807 EXPECT_EQ(6, GetOrderOfRequest(6));
808 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17809
810 // Make sure we test order of all requests made.
811 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53812}
813
814// Make sure that we count connecting sockets against the total limit.
815TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
816 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
817
818 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
819 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
820 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
821
822 // Create one asynchronous request.
823 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
824 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
825
[email protected]6b175382009-10-13 06:47:47826 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
827 // actually become pending until 2ms after they have been created. In order
828 // to flush all tasks, we need to wait so that we know there are no
829 // soon-to-be-pending tasks waiting.
830 PlatformThread::Sleep(10);
831 MessageLoop::current()->RunAllPending();
832
[email protected]211d21722009-07-22 15:48:53833 // The next synchronous request should wait for its turn.
834 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
835 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
836
[email protected]43a21b82010-06-10 21:30:54837 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53838
839 EXPECT_EQ(static_cast<int>(requests_.size()),
840 client_socket_factory_.allocation_count());
841
842 EXPECT_EQ(1, GetOrderOfRequest(1));
843 EXPECT_EQ(2, GetOrderOfRequest(2));
844 EXPECT_EQ(3, GetOrderOfRequest(3));
845 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17846 EXPECT_EQ(5, GetOrderOfRequest(5));
847
848 // Make sure we test order of all requests made.
849 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53850}
851
[email protected]6427fe22010-04-16 22:27:41852TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
853 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
854 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
855
856 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
857 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
858 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
859 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
860
861 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
862
863 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
864
865 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
866 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
867
868 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
869
870 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
871 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
872 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
873 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
874 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
875 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
876 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
877}
878
[email protected]d7027bb2010-05-10 18:58:54879TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
880 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
881 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
882
883 ClientSocketHandle handle;
884 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21885 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
886 &callback, pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54887
888 ClientSocketHandle handles[4];
889 for (size_t i = 0; i < arraysize(handles); ++i) {
890 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21891 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init("b", params_, kDefaultPriority,
892 &callback, pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54893 }
894
895 // One will be stalled, cancel all the handles now.
896 // This should hit the OnAvailableSocketSlot() code where we previously had
897 // stalled groups, but no longer have any.
898 for (size_t i = 0; i < arraysize(handles); ++i)
899 handles[i].Reset();
900}
901
[email protected]eb5a99382010-07-11 03:18:26902TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54903 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
904 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
905
[email protected]eb5a99382010-07-11 03:18:26906 {
907 ClientSocketHandle handles[kDefaultMaxSockets];
908 TestCompletionCallback callbacks[kDefaultMaxSockets];
909 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]e83326f2010-07-31 17:29:25910 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i), params_,
911 kDefaultPriority,
[email protected]df4b4ef2010-07-12 18:25:21912 &callbacks[i], pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26913 }
914
915 // Force a stalled group.
916 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54917 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21918 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
919 kDefaultPriority, &callback,
920 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26921
922 // Cancel the stalled request.
923 stalled_handle.Reset();
924
925 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
926 EXPECT_EQ(0, pool_->IdleSocketCount());
927
928 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54929 }
930
[email protected]43a21b82010-06-10 21:30:54931 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
932 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26933}
[email protected]43a21b82010-06-10 21:30:54934
[email protected]eb5a99382010-07-11 03:18:26935TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
936 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
937 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
938
939 {
940 ClientSocketHandle handles[kDefaultMaxSockets];
941 for (int i = 0; i < kDefaultMaxSockets; ++i) {
942 TestCompletionCallback callback;
[email protected]e83326f2010-07-31 17:29:25943 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i), params_,
[email protected]df4b4ef2010-07-12 18:25:21944 kDefaultPriority, &callback,
945 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26946 }
947
948 // Force a stalled group.
949 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
950 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54951 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21952 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
953 kDefaultPriority, &callback,
954 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26955
956 // Since it is stalled, it should have no connect jobs.
957 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
958
959 // Cancel the stalled request.
960 handles[0].Reset();
961
[email protected]eb5a99382010-07-11 03:18:26962 // Now we should have a connect job.
963 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
964
965 // The stalled socket should connect.
966 EXPECT_EQ(OK, callback.WaitForResult());
967
968 EXPECT_EQ(kDefaultMaxSockets + 1,
969 client_socket_factory_.allocation_count());
970 EXPECT_EQ(0, pool_->IdleSocketCount());
971 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
972
973 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54974 }
975
[email protected]eb5a99382010-07-11 03:18:26976 EXPECT_EQ(1, pool_->IdleSocketCount());
977}
[email protected]43a21b82010-06-10 21:30:54978
[email protected]eb5a99382010-07-11 03:18:26979TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
980 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
981 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:54982
[email protected]eb5a99382010-07-11 03:18:26983 ClientSocketHandle stalled_handle;
984 TestCompletionCallback callback;
985 {
986 ClientSocketHandle handles[kDefaultMaxSockets];
987 for (int i = 0; i < kDefaultMaxSockets; ++i) {
988 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21989 EXPECT_EQ(OK, handles[i].Init(StringPrintf("Take 2: %d", i), params_,
990 kDefaultPriority, &callback, pool_,
991 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26992 }
993
994 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
995 EXPECT_EQ(0, pool_->IdleSocketCount());
996
997 // Now we will hit the socket limit.
[email protected]df4b4ef2010-07-12 18:25:21998 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
999 kDefaultPriority, &callback,
1000 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261001
1002 // Dropping out of scope will close all handles and return them to idle.
1003 }
[email protected]43a21b82010-06-10 21:30:541004
1005 // But if we wait for it, the released idle sockets will be closed in
1006 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101007 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261008
1009 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1010 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541011}
1012
1013// Regression test for http://crbug.com/40952.
1014TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1015 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221016 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541017 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1018
1019 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1020 ClientSocketHandle handle;
1021 TestCompletionCallback callback;
[email protected]e83326f2010-07-31 17:29:251022 EXPECT_EQ(OK, handle.Init(base::IntToString(i), params_, kDefaultPriority,
[email protected]df4b4ef2010-07-12 18:25:211023 &callback, pool_, BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541024 }
1025
1026 // Flush all the DoReleaseSocket tasks.
1027 MessageLoop::current()->RunAllPending();
1028
1029 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1030 // reuse a socket.
1031 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1032 ClientSocketHandle handle;
1033 TestCompletionCallback callback;
1034
1035 // "0" is special here, since it should be the first entry in the sorted map,
1036 // which is the one which we would close an idle socket for. We shouldn't
1037 // close an idle socket though, since we should reuse the idle socket.
[email protected]df4b4ef2010-07-12 18:25:211038 EXPECT_EQ(OK, handle.Init("0", params_, kDefaultPriority, &callback, pool_,
1039 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541040
1041 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1042 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1043}
1044
[email protected]ab838892009-06-30 18:49:051045TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531046 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091047
[email protected]c9d6a1d2009-07-14 16:15:201048 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1049 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031050 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311051 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1052 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1053 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1054 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1055 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091056
[email protected]c9d6a1d2009-07-14 16:15:201057 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091058
[email protected]c9d6a1d2009-07-14 16:15:201059 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1060 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171061 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091062
[email protected]c9d6a1d2009-07-14 16:15:201063 EXPECT_EQ(1, GetOrderOfRequest(1));
1064 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031065 EXPECT_EQ(8, GetOrderOfRequest(3));
1066 EXPECT_EQ(6, GetOrderOfRequest(4));
1067 EXPECT_EQ(4, GetOrderOfRequest(5));
1068 EXPECT_EQ(3, GetOrderOfRequest(6));
1069 EXPECT_EQ(5, GetOrderOfRequest(7));
1070 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171071
1072 // Make sure we test order of all requests made.
[email protected]c9c6f5c2010-07-31 01:30:031073 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091074}
1075
[email protected]ab838892009-06-30 18:49:051076TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531077 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091078
[email protected]c9d6a1d2009-07-14 16:15:201079 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1080 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311081 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1082 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1083 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1084 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1085 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091086
[email protected]c9d6a1d2009-07-14 16:15:201087 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091088
[email protected]c9d6a1d2009-07-14 16:15:201089 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1090 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1091
1092 EXPECT_EQ(static_cast<int>(requests_.size()),
1093 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171094 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091095}
1096
1097// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051098// The pending connect job will be cancelled and should not call back into
1099// ClientSocketPoolBase.
1100TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531101 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201102
[email protected]ab838892009-06-30 18:49:051103 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061104 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211105 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1106 &req, pool_, BoundNetLog()));
[email protected]a6c59f62009-07-29 16:33:331107 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091108}
1109
[email protected]ab838892009-06-30 18:49:051110TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531111 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201112
[email protected]ab838892009-06-30 18:49:051113 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061114 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091115 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061116 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091117
[email protected]df4b4ef2010-07-12 18:25:211118 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1119 &callback, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091120
1121 handle.Reset();
1122
1123 TestCompletionCallback callback2;
[email protected]df4b4ef2010-07-12 18:25:211124 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1125 &callback2, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091126
1127 EXPECT_EQ(OK, callback2.WaitForResult());
1128 EXPECT_FALSE(callback.have_result());
1129
1130 handle.Reset();
1131}
1132
[email protected]ab838892009-06-30 18:49:051133TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531134 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091135
[email protected]c9d6a1d2009-07-14 16:15:201136 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1137 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311138 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1139 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1140 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1141 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1142 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091143
1144 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201145 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331146 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1147 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091148
[email protected]c9d6a1d2009-07-14 16:15:201149 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091150
[email protected]c9d6a1d2009-07-14 16:15:201151 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1152 client_socket_factory_.allocation_count());
1153 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171154 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091155
[email protected]c9d6a1d2009-07-14 16:15:201156 EXPECT_EQ(1, GetOrderOfRequest(1));
1157 EXPECT_EQ(2, GetOrderOfRequest(2));
1158 EXPECT_EQ(5, GetOrderOfRequest(3));
1159 EXPECT_EQ(3, GetOrderOfRequest(4));
1160 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1161 EXPECT_EQ(4, GetOrderOfRequest(6));
1162 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171163
1164 // Make sure we test order of all requests made.
1165 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091166}
1167
1168class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1169 public:
[email protected]2ab05b52009-07-01 23:57:581170 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241171 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581172 TestConnectJobFactory* test_connect_job_factory,
1173 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091174 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061175 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581176 within_callback_(false),
1177 test_connect_job_factory_(test_connect_job_factory),
1178 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091179
1180 virtual void RunWithParams(const Tuple1<int>& params) {
1181 callback_.RunWithParams(params);
1182 ASSERT_EQ(OK, params.a);
1183
1184 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581185 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111186
1187 // Don't allow reuse of the socket. Disconnect it and then release it and
1188 // run through the MessageLoop once to get it completely released.
1189 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091190 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111191 {
1192 MessageLoop::ScopedNestableTaskAllower nestable(
1193 MessageLoop::current());
1194 MessageLoop::current()->RunAllPending();
1195 }
[email protected]f6d1d6eb2009-06-24 20:16:091196 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471197 TestCompletionCallback next_job_callback;
[email protected]df4b4ef2010-07-12 18:25:211198 scoped_refptr<TestSocketParams> params = new TestSocketParams();
1199 int rv = handle_->Init("a", params, kDefaultPriority, &next_job_callback,
1200 pool_, BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581201 switch (next_job_type_) {
1202 case TestConnectJob::kMockJob:
1203 EXPECT_EQ(OK, rv);
1204 break;
1205 case TestConnectJob::kMockPendingJob:
1206 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471207
1208 // For pending jobs, wait for new socket to be created. This makes
1209 // sure there are no more pending operations nor any unclosed sockets
1210 // when the test finishes.
1211 // We need to give it a little bit of time to run, so that all the
1212 // operations that happen on timers (e.g. cleanup of idle
1213 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111214 {
1215 MessageLoop::ScopedNestableTaskAllower nestable(
1216 MessageLoop::current());
1217 PlatformThread::Sleep(10);
1218 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1219 }
[email protected]2ab05b52009-07-01 23:57:581220 break;
1221 default:
1222 FAIL() << "Unexpected job type: " << next_job_type_;
1223 break;
1224 }
[email protected]f6d1d6eb2009-06-24 20:16:091225 }
1226 }
1227
1228 int WaitForResult() {
1229 return callback_.WaitForResult();
1230 }
1231
1232 private:
1233 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241234 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091235 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581236 TestConnectJobFactory* const test_connect_job_factory_;
1237 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091238 TestCompletionCallback callback_;
1239};
1240
[email protected]2ab05b52009-07-01 23:57:581241TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531242 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201243
[email protected]0b7648c2009-07-06 20:14:011244 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061245 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581246 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061247 &handle, pool_.get(), connect_job_factory_,
1248 TestConnectJob::kMockPendingJob);
[email protected]df4b4ef2010-07-12 18:25:211249 int rv = handle.Init("a", params_, kDefaultPriority, &callback, pool_,
1250 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091251 ASSERT_EQ(ERR_IO_PENDING, rv);
1252
1253 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581254}
[email protected]f6d1d6eb2009-06-24 20:16:091255
[email protected]2ab05b52009-07-01 23:57:581256TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531257 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201258
[email protected]0b7648c2009-07-06 20:14:011259 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061260 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581261 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061262 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]df4b4ef2010-07-12 18:25:211263 int rv = handle.Init("a", params_, kDefaultPriority, &callback, pool_,
1264 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581265 ASSERT_EQ(ERR_IO_PENDING, rv);
1266
1267 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091268}
1269
1270// Make sure that pending requests get serviced after active requests get
1271// cancelled.
[email protected]ab838892009-06-30 18:49:051272TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531273 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201274
[email protected]0b7648c2009-07-06 20:14:011275 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091276
[email protected]c9d6a1d2009-07-14 16:15:201277 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1278 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1279 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1280 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1281 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1282 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1283 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091284
[email protected]c9d6a1d2009-07-14 16:15:201285 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1286 // Let's cancel them.
1287 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331288 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1289 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091290 }
1291
[email protected]f6d1d6eb2009-06-24 20:16:091292 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201293 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1294 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331295 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091296 }
1297
[email protected]75439d3b2009-07-23 22:11:171298 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091299}
1300
1301// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051302TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531303 const size_t kMaxSockets = 5;
1304 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201305
[email protected]0b7648c2009-07-06 20:14:011306 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091307
[email protected]211d21722009-07-22 15:48:531308 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1309 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091310
1311 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531312 for (size_t i = 0; i < kNumberOfRequests; ++i)
1313 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091314
[email protected]211d21722009-07-22 15:48:531315 for (size_t i = 0; i < kNumberOfRequests; ++i)
1316 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091317}
1318
[email protected]5fc08e32009-07-15 17:09:571319TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531320 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571321
1322 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1323
[email protected]a512f5982009-08-18 16:01:061324 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211325 int rv = req.handle()->Init("a", params_, kDefaultPriority, &req, pool_,
1326 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571327 EXPECT_EQ(ERR_IO_PENDING, rv);
1328
1329 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331330 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571331
[email protected]df4b4ef2010-07-12 18:25:211332 rv = req.handle()->Init("a", params_, kDefaultPriority, &req, pool_,
1333 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571334 EXPECT_EQ(ERR_IO_PENDING, rv);
1335 EXPECT_EQ(OK, req.WaitForResult());
1336
[email protected]a6c59f62009-07-29 16:33:331337 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171338 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571339 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1340}
1341
[email protected]2b7523d2009-07-29 20:29:231342// Regression test for http://crbug.com/17985.
1343TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1344 const int kMaxSockets = 3;
1345 const int kMaxSocketsPerGroup = 2;
1346 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1347
[email protected]ac790b42009-12-02 04:31:311348 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231349
1350 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1351 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1352
1353 // This is going to be a pending request in an otherwise empty group.
1354 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1355
1356 // Reach the maximum socket limit.
1357 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1358
1359 // Create a stalled group with high priorities.
1360 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1361 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231362
[email protected]eb5a99382010-07-11 03:18:261363 // Release the first two sockets from "a". Because this is a keepalive,
1364 // the first release will unblock the pending request for "a". The
1365 // second release will unblock a request for "c", becaue it is the next
1366 // high priority socket.
[email protected]2b7523d2009-07-29 20:29:231367 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1368 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1369
1370 // Closing idle sockets should not get us into trouble, but in the bug
1371 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411372 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541373 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261374
1375 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231376}
1377
[email protected]4d3b05d2010-01-27 21:27:291378TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531379 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571380
1381 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061382 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531383 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211384 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, log.bound());
[email protected]5fc08e32009-07-15 17:09:571385 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331386 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571387 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331388 EXPECT_TRUE(req.handle()->is_initialized());
1389 EXPECT_TRUE(req.handle()->socket());
1390 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301391
[email protected]06650c52010-06-03 00:49:171392 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461393 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531394 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171395 EXPECT_TRUE(LogContainsEvent(
1396 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1397 NetLog::PHASE_NONE));
1398 EXPECT_TRUE(LogContainsEvent(
1399 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1400 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461401 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171402 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571403}
1404
[email protected]4d3b05d2010-01-27 21:27:291405TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571406 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531407 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571408
1409 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061410 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531411 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181412 // Set the additional error state members to ensure that they get cleared.
1413 req.handle()->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431414 HttpResponseInfo info;
1415 info.headers = new HttpResponseHeaders("");
1416 req.handle()->set_ssl_error_response_info(info);
[email protected]df4b4ef2010-07-12 18:25:211417 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1418 &req, pool_, log.bound()));
[email protected]a6c59f62009-07-29 16:33:331419 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571420 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]e60e47a2010-07-14 03:37:181421 EXPECT_FALSE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:431422 EXPECT_TRUE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301423
[email protected]06650c52010-06-03 00:49:171424 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461425 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531426 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171427 EXPECT_TRUE(LogContainsEvent(
1428 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1429 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321430 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171431 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571432}
1433
[email protected]4d3b05d2010-01-27 21:27:291434TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101435 // TODO(eroman): Add back the log expectations! Removed them because the
1436 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531437 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571438
1439 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061440 TestSocketRequest req(&request_order_, &completion_count_);
1441 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571442
[email protected]df4b4ef2010-07-12 18:25:211443 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1444 &req, pool_, BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531445 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211446 EXPECT_EQ(ERR_IO_PENDING, req2.handle()->Init("a", params_, kDefaultPriority,
1447 &req2, pool_, BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571448
[email protected]a6c59f62009-07-29 16:33:331449 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571450
[email protected]fd7b7c92009-08-20 19:38:301451
1452 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301453
[email protected]5fc08e32009-07-15 17:09:571454 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331455 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301456
1457 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531458 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571459}
1460
[email protected]4d3b05d2010-01-27 21:27:291461TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341462 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1463
[email protected]17a0c6c2009-08-04 00:07:041464 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1465
[email protected]ac790b42009-12-02 04:31:311466 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1467 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1468 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1469 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341470
1471 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1472 requests_[2]->handle()->Reset();
1473 requests_[3]->handle()->Reset();
1474 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1475
1476 requests_[1]->handle()->Reset();
1477 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1478
1479 requests_[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261480 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341481}
1482
[email protected]5fc08e32009-07-15 17:09:571483// When requests and ConnectJobs are not coupled, the request will get serviced
1484// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291485TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531486 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571487
1488 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321489 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571490
[email protected]a512f5982009-08-18 16:01:061491 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211492 int rv = req1.handle()->Init("a", params_, kDefaultPriority, &req1, pool_,
1493 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571494 EXPECT_EQ(ERR_IO_PENDING, rv);
1495 EXPECT_EQ(OK, req1.WaitForResult());
1496
1497 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1498 // without a job.
1499 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1500
[email protected]a512f5982009-08-18 16:01:061501 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211502 rv = req2.handle()->Init("a", params_, kDefaultPriority, &req2, pool_,
1503 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571504 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061505 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211506 rv = req3.handle()->Init("a", params_, kDefaultPriority, &req3, pool_,
1507 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571508 EXPECT_EQ(ERR_IO_PENDING, rv);
1509
1510 // Both Requests 2 and 3 are pending. We release socket 1 which should
1511 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331512 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261513 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331514 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571515 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331516 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571517
1518 // Signal job 2, which should service request 3.
1519
1520 client_socket_factory_.SignalJobs();
1521 EXPECT_EQ(OK, req3.WaitForResult());
1522
1523 ASSERT_EQ(3U, request_order_.size());
1524 EXPECT_EQ(&req1, request_order_[0]);
1525 EXPECT_EQ(&req2, request_order_[1]);
1526 EXPECT_EQ(&req3, request_order_[2]);
1527 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1528}
1529
1530// The requests are not coupled to the jobs. So, the requests should finish in
1531// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291532TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531533 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571534 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321535 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571536
[email protected]a512f5982009-08-18 16:01:061537 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211538 int rv = req1.handle()->Init("a", params_, kDefaultPriority, &req1, pool_,
1539 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571540 EXPECT_EQ(ERR_IO_PENDING, rv);
1541
[email protected]a512f5982009-08-18 16:01:061542 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211543 rv = req2.handle()->Init("a", params_, kDefaultPriority, &req2, pool_,
1544 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571545 EXPECT_EQ(ERR_IO_PENDING, rv);
1546
1547 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321548 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571549
[email protected]a512f5982009-08-18 16:01:061550 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211551 rv = req3.handle()->Init("a", params_, kDefaultPriority, &req3, pool_,
1552 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571553 EXPECT_EQ(ERR_IO_PENDING, rv);
1554
1555 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1556 EXPECT_EQ(OK, req2.WaitForResult());
1557 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1558
1559 ASSERT_EQ(3U, request_order_.size());
1560 EXPECT_EQ(&req1, request_order_[0]);
1561 EXPECT_EQ(&req2, request_order_[1]);
1562 EXPECT_EQ(&req3, request_order_[2]);
1563}
1564
[email protected]e6ec67b2010-06-16 00:12:461565TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531566 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571567 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321568 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571569
[email protected]a512f5982009-08-18 16:01:061570 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211571 int rv = req1.handle()->Init("a", params_, kDefaultPriority, &req1, pool_,
1572 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571573 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331574 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571575
1576 MessageLoop::current()->RunAllPending();
1577
[email protected]a512f5982009-08-18 16:01:061578 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211579 rv = req2.handle()->Init("a", params_, kDefaultPriority, &req2, pool_,
1580 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571581 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]cfa8228c2010-06-17 01:07:561582 EXPECT_NE(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
1583 EXPECT_NE(LOAD_STATE_IDLE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571584}
1585
[email protected]e772db3f2010-07-12 18:11:131586TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1587 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1588 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1589
1590 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211591 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, req.handle()->Init("a", params_,
1592 kDefaultPriority,
1593 &req, pool_,
1594 BoundNetLog()));
[email protected]e772db3f2010-07-12 18:11:131595 EXPECT_TRUE(req.handle()->is_initialized());
1596 EXPECT_TRUE(req.handle()->socket());
1597 req.handle()->Reset();
1598}
1599
1600TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1601 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1602
1603 connect_job_factory_->set_job_type(
1604 TestConnectJob::kMockPendingRecoverableJob);
1605 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211606 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1607 &req, pool_, BoundNetLog()));
[email protected]e772db3f2010-07-12 18:11:131608 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1609 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, req.WaitForResult());
1610 EXPECT_TRUE(req.handle()->is_initialized());
1611 EXPECT_TRUE(req.handle()->socket());
1612 req.handle()->Reset();
1613}
1614
[email protected]e60e47a2010-07-14 03:37:181615TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1616 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1617 connect_job_factory_->set_job_type(
1618 TestConnectJob::kMockAdditionalErrorStateJob);
1619
1620 TestSocketRequest req(&request_order_, &completion_count_);
1621 EXPECT_EQ(ERR_CONNECTION_FAILED, req.handle()->Init("a", params_,
1622 kDefaultPriority, &req,
1623 pool_, BoundNetLog()));
1624 EXPECT_FALSE(req.handle()->is_initialized());
1625 EXPECT_FALSE(req.handle()->socket());
1626 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:431627 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181628 req.handle()->Reset();
1629}
1630
1631TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1632 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1633
1634 connect_job_factory_->set_job_type(
1635 TestConnectJob::kMockPendingAdditionalErrorStateJob);
1636 TestSocketRequest req(&request_order_, &completion_count_);
1637 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1638 &req, pool_, BoundNetLog()));
1639 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1640 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
1641 EXPECT_FALSE(req.handle()->is_initialized());
1642 EXPECT_FALSE(req.handle()->socket());
1643 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:431644 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181645 req.handle()->Reset();
1646}
1647
[email protected]4d3b05d2010-01-27 21:27:291648TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161649 CreatePoolWithIdleTimeouts(
1650 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1651 base::TimeDelta(), // Time out unused sockets immediately.
1652 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1653
1654 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1655
1656 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1657
1658 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211659 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161660 EXPECT_EQ(ERR_IO_PENDING, rv);
1661 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1662
1663 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211664 rv = req2.handle()->Init("a", params_, LOWEST, &req2, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161665 EXPECT_EQ(ERR_IO_PENDING, rv);
1666 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1667
1668 // Cancel one of the requests. Wait for the other, which will get the first
1669 // job. Release the socket. Run the loop again to make sure the second
1670 // socket is sitting idle and the first one is released (since ReleaseSocket()
1671 // just posts a DoReleaseSocket() task).
1672
1673 req.handle()->Reset();
1674 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:011675 // Use the socket.
1676 EXPECT_EQ(1, req2.handle()->socket()->Write(NULL, 1, NULL));
[email protected]9bf28db2009-08-29 01:35:161677 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471678
1679 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1680 // actually become pending until 2ms after they have been created. In order
1681 // to flush all tasks, we need to wait so that we know there are no
1682 // soon-to-be-pending tasks waiting.
1683 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161684 MessageLoop::current()->RunAllPending();
1685
1686 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041687
[email protected]9bf28db2009-08-29 01:35:161688 // Invoke the idle socket cleanup check. Only one socket should be left, the
1689 // used socket. Request it to make sure that it's used.
1690
1691 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531692 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211693 rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, log.bound());
[email protected]9bf28db2009-08-29 01:35:161694 EXPECT_EQ(OK, rv);
1695 EXPECT_TRUE(req.handle()->is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151696 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451697 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161698}
1699
[email protected]2041cf342010-02-19 03:15:591700// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161701// because of multiple releasing disconnected sockets.
1702TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1703 CreatePoolWithIdleTimeouts(
1704 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1705 base::TimeDelta(), // Time out unused sockets immediately.
1706 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1707
1708 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1709
1710 // Startup 4 connect jobs. Two of them will be pending.
1711
1712 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211713 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161714 EXPECT_EQ(OK, rv);
1715
1716 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211717 rv = req2.handle()->Init("a", params_, LOWEST, &req2, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161718 EXPECT_EQ(OK, rv);
1719
1720 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211721 rv = req3.handle()->Init("a", params_, LOWEST, &req3, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161722 EXPECT_EQ(ERR_IO_PENDING, rv);
1723
1724 TestSocketRequest req4(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211725 rv = req4.handle()->Init("a", params_, LOWEST, &req4, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161726 EXPECT_EQ(ERR_IO_PENDING, rv);
1727
1728 // Release two disconnected sockets.
1729
1730 req.handle()->socket()->Disconnect();
1731 req.handle()->Reset();
1732 req2.handle()->socket()->Disconnect();
1733 req2.handle()->Reset();
1734
1735 EXPECT_EQ(OK, req3.WaitForResult());
1736 EXPECT_FALSE(req3.handle()->is_reused());
1737 EXPECT_EQ(OK, req4.WaitForResult());
1738 EXPECT_FALSE(req4.handle()->is_reused());
1739}
1740
[email protected]d7027bb2010-05-10 18:58:541741// Regression test for http://crbug.com/42267.
1742// When DoReleaseSocket() is processed for one socket, it is blocked because the
1743// other stalled groups all have releasing sockets, so no progress can be made.
1744TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1745 CreatePoolWithIdleTimeouts(
1746 4 /* socket limit */, 4 /* socket limit per group */,
1747 base::TimeDelta(), // Time out unused sockets immediately.
1748 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1749
1750 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1751
1752 // Max out the socket limit with 2 per group.
1753
1754 scoped_ptr<TestSocketRequest> req_a[4];
1755 scoped_ptr<TestSocketRequest> req_b[4];
1756
1757 for (int i = 0; i < 2; ++i) {
1758 req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1759 req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
[email protected]df4b4ef2010-07-12 18:25:211760 EXPECT_EQ(OK, req_a[i]->handle()->Init("a", params_, LOWEST, req_a[i].get(),
1761 pool_, BoundNetLog()));
1762 EXPECT_EQ(OK, req_b[i]->handle()->Init("b", params_, LOWEST, req_b[i].get(),
1763 pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541764 }
[email protected]b89f7e42010-05-20 20:37:001765
[email protected]d7027bb2010-05-10 18:58:541766 // Make 4 pending requests, 2 per group.
1767
1768 for (int i = 2; i < 4; ++i) {
1769 req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1770 req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
[email protected]df4b4ef2010-07-12 18:25:211771 EXPECT_EQ(ERR_IO_PENDING, req_a[i]->handle()->Init("a", params_, LOWEST,
1772 req_a[i].get(), pool_,
1773 BoundNetLog()));
1774 EXPECT_EQ(ERR_IO_PENDING, req_b[i]->handle()->Init("b", params_, LOWEST,
1775 req_b[i].get(), pool_,
1776 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541777 }
1778
1779 // Release b's socket first. The order is important, because in
1780 // DoReleaseSocket(), we'll process b's released socket, and since both b and
1781 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
1782 // first, which has a releasing socket, so it refuses to start up another
1783 // ConnectJob. So, we used to infinite loop on this.
1784 req_b[0]->handle()->socket()->Disconnect();
1785 req_b[0]->handle()->Reset();
1786 req_a[0]->handle()->socket()->Disconnect();
1787 req_a[0]->handle()->Reset();
1788
1789 // Used to get stuck here.
1790 MessageLoop::current()->RunAllPending();
1791
1792 req_b[1]->handle()->socket()->Disconnect();
1793 req_b[1]->handle()->Reset();
1794 req_a[1]->handle()->socket()->Disconnect();
1795 req_a[1]->handle()->Reset();
1796
1797 for (int i = 2; i < 4; ++i) {
1798 EXPECT_EQ(OK, req_b[i]->WaitForResult());
1799 EXPECT_EQ(OK, req_a[i]->WaitForResult());
1800 }
1801}
1802
[email protected]fd4fe0b2010-02-08 23:02:151803TEST_F(ClientSocketPoolBaseTest,
1804 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
1805 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1806
1807 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1808
1809 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1810 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1811 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1812 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1813
1814 EXPECT_EQ(OK, requests_[0]->WaitForResult());
1815 EXPECT_EQ(OK, requests_[1]->WaitForResult());
1816 EXPECT_EQ(2u, completion_count_);
1817
1818 // Releases one connection.
1819 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1820 EXPECT_EQ(OK, requests_[2]->WaitForResult());
1821
1822 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1823 EXPECT_EQ(OK, requests_[3]->WaitForResult());
1824 EXPECT_EQ(4u, completion_count_);
1825
1826 EXPECT_EQ(1, GetOrderOfRequest(1));
1827 EXPECT_EQ(2, GetOrderOfRequest(2));
1828 EXPECT_EQ(3, GetOrderOfRequest(3));
1829 EXPECT_EQ(4, GetOrderOfRequest(4));
1830
1831 // Make sure we test order of all requests made.
1832 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5));
1833}
1834
[email protected]4f1e4982010-03-02 18:31:041835class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
1836 public:
[email protected]e60e47a2010-07-14 03:37:181837 TestReleasingSocketRequest(TestClientSocketPool* pool, int expected_result,
1838 bool reset_releasing_handle)
1839 : pool_(pool),
1840 expected_result_(expected_result),
1841 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:041842
1843 ClientSocketHandle* handle() { return &handle_; }
1844
1845 int WaitForResult() {
1846 return callback_.WaitForResult();
1847 }
1848
1849 virtual void RunWithParams(const Tuple1<int>& params) {
1850 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:181851 if (reset_releasing_handle_)
1852 handle_.Reset();
[email protected]df4b4ef2010-07-12 18:25:211853 scoped_refptr<TestSocketParams> con_params = new TestSocketParams();
[email protected]e60e47a2010-07-14 03:37:181854 EXPECT_EQ(expected_result_, handle2_.Init("a", con_params, kDefaultPriority,
1855 &callback2_, pool_,
1856 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:041857 }
1858
1859 private:
[email protected]df4b4ef2010-07-12 18:25:211860 scoped_refptr<TestClientSocketPool> pool_;
[email protected]e60e47a2010-07-14 03:37:181861 int expected_result_;
1862 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:041863 ClientSocketHandle handle_;
1864 ClientSocketHandle handle2_;
1865 TestCompletionCallback callback_;
1866 TestCompletionCallback callback2_;
1867};
1868
[email protected]e60e47a2010-07-14 03:37:181869
1870TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
1871 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1872
1873 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1874 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1875 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1876
1877 EXPECT_EQ(static_cast<int>(requests_.size()),
1878 client_socket_factory_.allocation_count());
1879
1880 connect_job_factory_->set_job_type(
1881 TestConnectJob::kMockPendingAdditionalErrorStateJob);
1882 TestReleasingSocketRequest req(pool_.get(), OK, false);
1883 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1884 &req, pool_, BoundNetLog()));
1885 // The next job should complete synchronously
1886 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1887
1888 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
1889 EXPECT_FALSE(req.handle()->is_initialized());
1890 EXPECT_FALSE(req.handle()->socket());
1891 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:431892 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181893}
1894
[email protected]b6501d3d2010-06-03 23:53:341895// http://crbug.com/44724 regression test.
1896// We start releasing the pool when we flush on network change. When that
1897// happens, the only active references are in the ClientSocketHandles. When a
1898// ConnectJob completes and calls back into the last ClientSocketHandle, that
1899// callback can release the last reference and delete the pool. After the
1900// callback finishes, we go back to the stack frame within the now-deleted pool.
1901// Executing any code that refers to members of the now-deleted pool can cause
1902// crashes.
1903TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
1904 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1905 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1906
1907 ClientSocketHandle handle;
1908 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211909 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1910 &callback, pool_, BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:341911
1912 // Simulate flushing the pool.
1913 pool_ = NULL;
1914
1915 // We'll call back into this now.
1916 callback.WaitForResult();
1917}
1918
[email protected]a7e38572010-06-07 18:22:241919TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
1920 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1921 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1922
1923 ClientSocketHandle handle;
1924 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211925 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1926 &callback, pool_, BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:241927 EXPECT_EQ(OK, callback.WaitForResult());
1928 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
1929
1930 pool_->Flush();
1931
1932 handle.Reset();
1933 MessageLoop::current()->RunAllPending();
1934
[email protected]df4b4ef2010-07-12 18:25:211935 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1936 &callback, pool_, BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:241937 EXPECT_EQ(OK, callback.WaitForResult());
1938 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
1939}
1940
[email protected]06f92462010-08-31 19:24:141941class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
1942 public:
1943 ConnectWithinCallback(
1944 const std::string& group_name,
1945 const scoped_refptr<TestSocketParams>& params,
1946 const scoped_refptr<TestClientSocketPool>& pool)
1947 : group_name_(group_name), params_(params), pool_(pool) {}
1948
1949 ~ConnectWithinCallback() {}
1950
1951 virtual void RunWithParams(const Tuple1<int>& params) {
1952 callback_.RunWithParams(params);
1953 EXPECT_EQ(ERR_IO_PENDING,
1954 handle_.Init(group_name_,
1955 params_,
1956 kDefaultPriority,
1957 &nested_callback_,
1958 pool_,
1959 BoundNetLog()));
1960 }
1961
1962 int WaitForResult() {
1963 return callback_.WaitForResult();
1964 }
1965
1966 int WaitForNestedResult() {
1967 return nested_callback_.WaitForResult();
1968 }
1969
1970 private:
1971 const std::string group_name_;
1972 const scoped_refptr<TestSocketParams> params_;
1973 const scoped_refptr<TestClientSocketPool> pool_;
1974 ClientSocketHandle handle_;
1975 TestCompletionCallback callback_;
1976 TestCompletionCallback nested_callback_;
1977};
1978
1979TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
1980 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1981
1982 // First job will be waiting until it gets aborted.
1983 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1984
1985 ClientSocketHandle handle;
1986 ConnectWithinCallback callback("a", params_, pool_);
1987 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1988 &callback, pool_, BoundNetLog()));
1989
1990 // Second job will be started during the first callback, and will
1991 // asynchronously complete with OK.
1992 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1993 pool_->Flush();
1994 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
1995 EXPECT_EQ(OK, callback.WaitForNestedResult());
1996}
1997
[email protected]25eea382010-07-10 23:55:261998// Cancel a pending socket request while we're at max sockets,
1999// and verify that the backup socket firing doesn't cause a crash.
2000TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2001 // Max 4 sockets globally, max 4 sockets per group.
2002 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222003 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262004
[email protected]4baaf9d2010-08-31 15:15:442005 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2006 // timer.
[email protected]25eea382010-07-10 23:55:262007 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2008 ClientSocketHandle handle;
2009 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:212010 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar", params_, kDefaultPriority,
2011 &callback, pool_, BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262012
2013 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2014 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2015 ClientSocketHandle handles[kDefaultMaxSockets];
2016 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2017 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:212018 EXPECT_EQ(OK, handles[i].Init("bar", params_, kDefaultPriority, &callback,
2019 pool_, BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262020 }
2021
2022 MessageLoop::current()->RunAllPending();
2023
2024 // Cancel the pending request.
2025 handle.Reset();
2026
2027 // Wait for the backup timer to fire (add some slop to ensure it fires)
2028 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2029
2030 MessageLoop::current()->RunAllPending();
2031 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2032}
2033
[email protected]4baaf9d2010-08-31 15:15:442034TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketWhenThereAreNoRequests) {
2035 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2036 pool_->EnableConnectBackupJobs();
2037
2038 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2039 // timer.
2040 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2041 ClientSocketHandle handle;
2042 TestCompletionCallback callback;
2043 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar", params_, kDefaultPriority,
2044 &callback, pool_, BoundNetLog()));
2045 ASSERT_TRUE(pool_->HasGroup("bar"));
2046 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2047
2048 // Cancel the socket request. This should cancel the backup timer. Wait for
2049 // the backup time to see if it indeed got canceled.
2050 handle.Reset();
2051 // Wait for the backup timer to fire (add some slop to ensure it fires)
2052 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2053 MessageLoop::current()->RunAllPending();
2054 ASSERT_TRUE(pool_->HasGroup("bar"));
2055 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2056}
2057
[email protected]eb5a99382010-07-11 03:18:262058// Test delayed socket binding for the case where we have two connects,
2059// and while one is waiting on a connect, the other frees up.
2060// The socket waiting on a connect should switch immediately to the freed
2061// up socket.
2062TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2063 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2064 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2065
2066 ClientSocketHandle handle1;
2067 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:212068 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
2069 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262070 EXPECT_EQ(OK, callback.WaitForResult());
2071
2072 // No idle sockets, no pending jobs.
2073 EXPECT_EQ(0, pool_->IdleSocketCount());
2074 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2075
2076 // Create a second socket to the same host, but this one will wait.
2077 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2078 ClientSocketHandle handle2;
[email protected]df4b4ef2010-07-12 18:25:212079 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
2080 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262081 // No idle sockets, and one connecting job.
2082 EXPECT_EQ(0, pool_->IdleSocketCount());
2083 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2084
2085 // Return the first handle to the pool. This will initiate the delayed
2086 // binding.
2087 handle1.Reset();
2088
2089 MessageLoop::current()->RunAllPending();
2090
2091 // Still no idle sockets, still one pending connect job.
2092 EXPECT_EQ(0, pool_->IdleSocketCount());
2093 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2094
2095 // The second socket connected, even though it was a Waiting Job.
2096 EXPECT_EQ(OK, callback.WaitForResult());
2097
2098 // And we can see there is still one job waiting.
2099 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2100
2101 // Finally, signal the waiting Connect.
2102 client_socket_factory_.SignalJobs();
2103 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2104
2105 MessageLoop::current()->RunAllPending();
2106}
2107
2108// Test delayed socket binding when a group is at capacity and one
2109// of the group's sockets frees up.
2110TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2111 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2112 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2113
2114 ClientSocketHandle handle1;
2115 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:212116 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
2117 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262118 EXPECT_EQ(OK, callback.WaitForResult());
2119
2120 // No idle sockets, no pending jobs.
2121 EXPECT_EQ(0, pool_->IdleSocketCount());
2122 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2123
2124 // Create a second socket to the same host, but this one will wait.
2125 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2126 ClientSocketHandle handle2;
[email protected]df4b4ef2010-07-12 18:25:212127 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
2128 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262129 // No idle sockets, and one connecting job.
2130 EXPECT_EQ(0, pool_->IdleSocketCount());
2131 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2132
2133 // Return the first handle to the pool. This will initiate the delayed
2134 // binding.
2135 handle1.Reset();
2136
2137 MessageLoop::current()->RunAllPending();
2138
2139 // Still no idle sockets, still one pending connect job.
2140 EXPECT_EQ(0, pool_->IdleSocketCount());
2141 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2142
2143 // The second socket connected, even though it was a Waiting Job.
2144 EXPECT_EQ(OK, callback.WaitForResult());
2145
2146 // And we can see there is still one job waiting.
2147 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2148
2149 // Finally, signal the waiting Connect.
2150 client_socket_factory_.SignalJobs();
2151 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2152
2153 MessageLoop::current()->RunAllPending();
2154}
2155
2156// Test out the case where we have one socket connected, one
2157// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512158// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262159// should complete, by taking the first socket's idle socket.
2160TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2161 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2162 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2163
2164 ClientSocketHandle handle1;
2165 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:212166 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
2167 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262168 EXPECT_EQ(OK, callback.WaitForResult());
2169
2170 // No idle sockets, no pending jobs.
2171 EXPECT_EQ(0, pool_->IdleSocketCount());
2172 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2173
2174 // Create a second socket to the same host, but this one will wait.
2175 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2176 ClientSocketHandle handle2;
[email protected]df4b4ef2010-07-12 18:25:212177 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
2178 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262179 // No idle sockets, and one connecting job.
2180 EXPECT_EQ(0, pool_->IdleSocketCount());
2181 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2182
2183 // Return the first handle to the pool. This will initiate the delayed
2184 // binding.
2185 handle1.Reset();
2186
2187 MessageLoop::current()->RunAllPending();
2188
2189 // Still no idle sockets, still one pending connect job.
2190 EXPECT_EQ(0, pool_->IdleSocketCount());
2191 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2192
2193 // The second socket connected, even though it was a Waiting Job.
2194 EXPECT_EQ(OK, callback.WaitForResult());
2195
2196 // And we can see there is still one job waiting.
2197 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2198
2199 // Finally, signal the waiting Connect.
2200 client_socket_factory_.SignalJobs();
2201 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2202
2203 MessageLoop::current()->RunAllPending();
2204}
2205
[email protected]2abfe90a2010-08-25 17:49:512206// Cover the case where on an available socket slot, we have one pending
2207// request that completes synchronously, thereby making the Group empty.
2208TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2209 const int kUnlimitedSockets = 100;
2210 const int kOneSocketPerGroup = 1;
2211 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2212
2213 // Make the first request asynchronous fail.
2214 // This will free up a socket slot later.
2215 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2216
2217 ClientSocketHandle handle1;
2218 TestCompletionCallback callback1;
2219 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
2220 &callback1, pool_, BoundNetLog()));
2221 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2222
2223 // Make the second request synchronously fail. This should make the Group
2224 // empty.
2225 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2226 ClientSocketHandle handle2;
2227 TestCompletionCallback callback2;
2228 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2229 // when created.
2230 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
2231 &callback2, pool_, BoundNetLog()));
2232
2233 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2234
2235 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2236 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2237 EXPECT_FALSE(pool_->HasGroup("a"));
2238}
2239
[email protected]f6d1d6eb2009-06-24 20:16:092240} // namespace
2241
2242} // namespace net