1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/socket/transport_client_socket_pool.h"
6
7 #include <stdint.h>
8 #include <utility>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/callback_helpers.h"
14 #include "base/check_op.h"
15 #include "base/location.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/notreached.h"
19 #include "base/optional.h"
20 #include "base/run_loop.h"
21 #include "base/single_thread_task_runner.h"
22 #include "base/stl_util.h"
23 #include "base/strings/string_number_conversions.h"
24 #include "base/strings/stringprintf.h"
25 #include "base/test/scoped_feature_list.h"
26 #include "base/threading/platform_thread.h"
27 #include "base/threading/thread_task_runner_handle.h"
28 #include "base/values.h"
29 #include "net/base/features.h"
30 #include "net/base/load_timing_info.h"
31 #include "net/base/load_timing_info_test_util.h"
32 #include "net/base/net_errors.h"
33 #include "net/base/network_isolation_key.h"
34 #include "net/base/privacy_mode.h"
35 #include "net/base/proxy_server.h"
36 #include "net/base/request_priority.h"
37 #include "net/base/test_completion_callback.h"
38 #include "net/dns/public/resolve_error_info.h"
39 #include "net/http/http_response_headers.h"
40 #include "net/http/http_response_info.h"
41 #include "net/log/net_log.h"
42 #include "net/log/net_log_event_type.h"
43 #include "net/log/net_log_source.h"
44 #include "net/log/net_log_source_type.h"
45 #include "net/log/test_net_log.h"
46 #include "net/log/test_net_log_util.h"
47 #include "net/socket/client_socket_factory.h"
48 #include "net/socket/client_socket_handle.h"
49 #include "net/socket/datagram_client_socket.h"
50 #include "net/socket/socket_performance_watcher.h"
51 #include "net/socket/socket_tag.h"
52 #include "net/socket/socket_test_util.h"
53 #include "net/socket/ssl_client_socket.h"
54 #include "net/socket/stream_socket.h"
55 #include "net/socket/transport_connect_job.h"
56 #include "net/ssl/ssl_cert_request_info.h"
57 #include "net/test/gtest_util.h"
58 #include "net/test/test_with_task_environment.h"
59 #include "net/traffic_annotation/network_traffic_annotation.h"
60 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
61 #include "testing/gmock/include/gmock/gmock.h"
62 #include "testing/gtest/include/gtest/gtest.h"
63
64 using net::test::IsError;
65 using net::test::IsOk;
66
67 using ::testing::Invoke;
68 using ::testing::Return;
69
70 namespace net {
71
72 namespace {
73
74 const int kDefaultMaxSockets = 4;
75 const int kDefaultMaxSocketsPerGroup = 2;
76 constexpr base::TimeDelta kUnusedIdleSocketTimeout =
77 base::TimeDelta::FromSeconds(10);
78
TestGroupId(const std::string & host,int port=80,ClientSocketPool::SocketType socket_type=ClientSocketPool::SocketType::kHttp,PrivacyMode privacy_mode=PrivacyMode::PRIVACY_MODE_DISABLED,NetworkIsolationKey network_isolation_key=NetworkIsolationKey ())79 ClientSocketPool::GroupId TestGroupId(
80 const std::string& host,
81 int port = 80,
82 ClientSocketPool::SocketType socket_type =
83 ClientSocketPool::SocketType::kHttp,
84 PrivacyMode privacy_mode = PrivacyMode::PRIVACY_MODE_DISABLED,
85 NetworkIsolationKey network_isolation_key = NetworkIsolationKey()) {
86 bool disable_secure_dns = false;
87 return ClientSocketPool::GroupId(HostPortPair(host, port), socket_type,
88 privacy_mode, network_isolation_key,
89 disable_secure_dns);
90 }
91
92 // Make sure |handle| sets load times correctly when it has been assigned a
93 // reused socket.
TestLoadTimingInfoConnectedReused(const ClientSocketHandle & handle)94 void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
95 LoadTimingInfo load_timing_info;
96 // Only pass true in as |is_reused|, as in general, HttpStream types should
97 // have stricter concepts of reuse than socket pools.
98 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
99
100 EXPECT_EQ(true, load_timing_info.socket_reused);
101 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
102
103 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
104 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
105 }
106
107 // Make sure |handle| sets load times correctly when it has been assigned a
108 // fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
109 // of a connection where |is_reused| is false may consider the connection
110 // reused.
TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle & handle)111 void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
112 EXPECT_FALSE(handle.is_reused());
113
114 LoadTimingInfo load_timing_info;
115 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
116
117 EXPECT_FALSE(load_timing_info.socket_reused);
118 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
119
120 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
121 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
122 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
123
124 TestLoadTimingInfoConnectedReused(handle);
125 }
126
127 // Make sure |handle| sets load times correctly, in the case that it does not
128 // currently have a socket.
TestLoadTimingInfoNotConnected(const ClientSocketHandle & handle)129 void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
130 // Should only be set to true once a socket is assigned, if at all.
131 EXPECT_FALSE(handle.is_reused());
132
133 LoadTimingInfo load_timing_info;
134 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
135
136 EXPECT_FALSE(load_timing_info.socket_reused);
137 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
138
139 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
140 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
141 }
142
143 class MockClientSocket : public StreamSocket {
144 public:
MockClientSocket(net::NetLog * net_log)145 explicit MockClientSocket(net::NetLog* net_log)
146 : connected_(false),
147 has_unread_data_(false),
148 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)),
149 was_used_to_convey_data_(false) {}
150
151 // Sets whether the socket has unread data. If true, the next call to Read()
152 // will return 1 byte and IsConnectedAndIdle() will return false.
set_has_unread_data(bool has_unread_data)153 void set_has_unread_data(bool has_unread_data) {
154 has_unread_data_ = has_unread_data;
155 }
156
157 // Socket implementation.
Read(IOBuffer *,int len,CompletionOnceCallback)158 int Read(IOBuffer* /* buf */,
159 int len,
160 CompletionOnceCallback /* callback */) override {
161 if (has_unread_data_ && len > 0) {
162 has_unread_data_ = false;
163 was_used_to_convey_data_ = true;
164 return 1;
165 }
166 return ERR_UNEXPECTED;
167 }
168
Write(IOBuffer *,int len,CompletionOnceCallback,const NetworkTrafficAnnotationTag &)169 int Write(
170 IOBuffer* /* buf */,
171 int len,
172 CompletionOnceCallback /* callback */,
173 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
174 was_used_to_convey_data_ = true;
175 return len;
176 }
SetReceiveBufferSize(int32_t size)177 int SetReceiveBufferSize(int32_t size) override { return OK; }
SetSendBufferSize(int32_t size)178 int SetSendBufferSize(int32_t size) override { return OK; }
179
180 // StreamSocket implementation.
Connect(CompletionOnceCallback callback)181 int Connect(CompletionOnceCallback callback) override {
182 connected_ = true;
183 return OK;
184 }
185
Disconnect()186 void Disconnect() override { connected_ = false; }
IsConnected() const187 bool IsConnected() const override { return connected_; }
IsConnectedAndIdle() const188 bool IsConnectedAndIdle() const override {
189 return connected_ && !has_unread_data_;
190 }
191
GetPeerAddress(IPEndPoint *) const192 int GetPeerAddress(IPEndPoint* /* address */) const override {
193 return ERR_UNEXPECTED;
194 }
195
GetLocalAddress(IPEndPoint *) const196 int GetLocalAddress(IPEndPoint* /* address */) const override {
197 return ERR_UNEXPECTED;
198 }
199
NetLog() const200 const NetLogWithSource& NetLog() const override { return net_log_; }
201
WasEverUsed() const202 bool WasEverUsed() const override { return was_used_to_convey_data_; }
WasAlpnNegotiated() const203 bool WasAlpnNegotiated() const override { return false; }
GetNegotiatedProtocol() const204 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
GetSSLInfo(SSLInfo * ssl_info)205 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
GetConnectionAttempts(ConnectionAttempts * out) const206 void GetConnectionAttempts(ConnectionAttempts* out) const override {
207 out->clear();
208 }
ClearConnectionAttempts()209 void ClearConnectionAttempts() override {}
AddConnectionAttempts(const ConnectionAttempts & attempts)210 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
GetTotalReceivedBytes() const211 int64_t GetTotalReceivedBytes() const override {
212 NOTIMPLEMENTED();
213 return 0;
214 }
ApplySocketTag(const SocketTag & tag)215 void ApplySocketTag(const SocketTag& tag) override {}
216
217 private:
218 bool connected_;
219 bool has_unread_data_;
220 NetLogWithSource net_log_;
221 bool was_used_to_convey_data_;
222
223 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
224 };
225
226 class TestConnectJob;
227
228 class MockClientSocketFactory : public ClientSocketFactory {
229 public:
MockClientSocketFactory()230 MockClientSocketFactory() : allocation_count_(0) {}
231
CreateDatagramClientSocket(DatagramSocket::BindType bind_type,NetLog * net_log,const NetLogSource & source)232 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
233 DatagramSocket::BindType bind_type,
234 NetLog* net_log,
235 const NetLogSource& source) override {
236 NOTREACHED();
237 return nullptr;
238 }
239
CreateTransportClientSocket(const AddressList & addresses,std::unique_ptr<SocketPerformanceWatcher>,NetworkQualityEstimator *,NetLog *,const NetLogSource &)240 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
241 const AddressList& addresses,
242 std::unique_ptr<
243 SocketPerformanceWatcher> /* socket_performance_watcher */,
244 NetworkQualityEstimator* /* network_quality_estimator */,
245 NetLog* /* net_log */,
246 const NetLogSource& /*source*/) override {
247 allocation_count_++;
248 return nullptr;
249 }
250
CreateSSLClientSocket(SSLClientContext * context,std::unique_ptr<StreamSocket> stream_socket,const HostPortPair & host_and_port,const SSLConfig & ssl_config)251 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
252 SSLClientContext* context,
253 std::unique_ptr<StreamSocket> stream_socket,
254 const HostPortPair& host_and_port,
255 const SSLConfig& ssl_config) override {
256 NOTIMPLEMENTED();
257 return nullptr;
258 }
259
CreateProxyClientSocket(std::unique_ptr<StreamSocket> stream_socket,const std::string & user_agent,const HostPortPair & endpoint,const ProxyServer & proxy_server,HttpAuthController * http_auth_controller,bool tunnel,bool using_spdy,NextProto negotiated_protocol,ProxyDelegate * proxy_delegate,const NetworkTrafficAnnotationTag & traffic_annotation)260 std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
261 std::unique_ptr<StreamSocket> stream_socket,
262 const std::string& user_agent,
263 const HostPortPair& endpoint,
264 const ProxyServer& proxy_server,
265 HttpAuthController* http_auth_controller,
266 bool tunnel,
267 bool using_spdy,
268 NextProto negotiated_protocol,
269 ProxyDelegate* proxy_delegate,
270 const NetworkTrafficAnnotationTag& traffic_annotation) override {
271 NOTIMPLEMENTED();
272 return nullptr;
273 }
274
WaitForSignal(TestConnectJob * job)275 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
276
277 void SignalJobs();
278
279 void SignalJob(size_t job);
280
281 void SetJobLoadState(size_t job, LoadState load_state);
282
283 // Sets the HasConnectionEstablished value of the specified job to true,
284 // without invoking the callback.
285 void SetJobHasEstablishedConnection(size_t job);
286
allocation_count() const287 int allocation_count() const { return allocation_count_; }
288
289 private:
290 int allocation_count_;
291 std::vector<TestConnectJob*> waiting_jobs_;
292 };
293
294 class TestConnectJob : public ConnectJob {
295 public:
296 enum JobType {
297 kMockJob,
298 kMockFailingJob,
299 kMockPendingJob,
300 kMockPendingFailingJob,
301 kMockWaitingJob,
302
303 // Certificate errors return a socket in addition to an error code.
304 kMockCertErrorJob,
305 kMockPendingCertErrorJob,
306
307 kMockAdditionalErrorStateJob,
308 kMockPendingAdditionalErrorStateJob,
309 kMockUnreadDataJob,
310
311 kMockAuthChallengeOnceJob,
312 kMockAuthChallengeTwiceJob,
313 kMockAuthChallengeOnceFailingJob,
314 kMockAuthChallengeTwiceFailingJob,
315 };
316
317 // The kMockPendingJob uses a slight delay before allowing the connect
318 // to complete.
319 static const int kPendingConnectDelay = 2;
320
TestConnectJob(JobType job_type,RequestPriority request_priority,SocketTag socket_tag,base::TimeDelta timeout_duration,const CommonConnectJobParams * common_connect_job_params,ConnectJob::Delegate * delegate,MockClientSocketFactory * client_socket_factory)321 TestConnectJob(JobType job_type,
322 RequestPriority request_priority,
323 SocketTag socket_tag,
324 base::TimeDelta timeout_duration,
325 const CommonConnectJobParams* common_connect_job_params,
326 ConnectJob::Delegate* delegate,
327 MockClientSocketFactory* client_socket_factory)
328 : ConnectJob(request_priority,
329 socket_tag,
330 timeout_duration,
331 common_connect_job_params,
332 delegate,
333 nullptr /* net_log */,
334 NetLogSourceType::TRANSPORT_CONNECT_JOB,
335 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
336 job_type_(job_type),
337 client_socket_factory_(client_socket_factory),
338 load_state_(LOAD_STATE_IDLE),
339 has_established_connection_(false),
340 store_additional_error_state_(false) {}
341
Signal()342 void Signal() {
343 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
344 }
345
set_load_state(LoadState load_state)346 void set_load_state(LoadState load_state) { load_state_ = load_state; }
347
set_has_established_connection()348 void set_has_established_connection() {
349 DCHECK(!has_established_connection_);
350 has_established_connection_ = true;
351 }
352
353 // From ConnectJob:
354
GetLoadState() const355 LoadState GetLoadState() const override { return load_state_; }
356
HasEstablishedConnection() const357 bool HasEstablishedConnection() const override {
358 return has_established_connection_;
359 }
360
GetResolveErrorInfo() const361 ResolveErrorInfo GetResolveErrorInfo() const override {
362 return ResolveErrorInfo(OK);
363 }
364
IsSSLError() const365 bool IsSSLError() const override { return store_additional_error_state_; }
366
GetCertRequestInfo()367 scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override {
368 if (store_additional_error_state_)
369 return base::MakeRefCounted<SSLCertRequestInfo>();
370 return nullptr;
371 }
372
373 private:
374 // From ConnectJob:
375
ConnectInternal()376 int ConnectInternal() override {
377 AddressList ignored;
378 client_socket_factory_->CreateTransportClientSocket(
379 ignored, nullptr, nullptr, nullptr, NetLogSource());
380 switch (job_type_) {
381 case kMockJob:
382 return DoConnect(true /* successful */, false /* sync */,
383 false /* cert_error */);
384 case kMockFailingJob:
385 return DoConnect(false /* error */, false /* sync */,
386 false /* cert_error */);
387 case kMockPendingJob:
388 set_load_state(LOAD_STATE_CONNECTING);
389
390 // Depending on execution timings, posting a delayed task can result
391 // in the task getting executed the at the earliest possible
392 // opportunity or only after returning once from the message loop and
393 // then a second call into the message loop. In order to make behavior
394 // more deterministic, we change the default delay to 2ms. This should
395 // always require us to wait for the second call into the message loop.
396 //
397 // N.B. The correct fix for this and similar timing problems is to
398 // abstract time for the purpose of unittests. Unfortunately, we have
399 // a lot of third-party components that directly call the various
400 // time functions, so this change would be rather invasive.
401 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
402 FROM_HERE,
403 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
404 weak_factory_.GetWeakPtr(), true /* successful */,
405 true /* async */, false /* cert_error */),
406 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
407 return ERR_IO_PENDING;
408 case kMockPendingFailingJob:
409 set_load_state(LOAD_STATE_CONNECTING);
410 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
411 FROM_HERE,
412 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
413 weak_factory_.GetWeakPtr(), false /* error */,
414 true /* async */, false /* cert_error */),
415 base::TimeDelta::FromMilliseconds(2));
416 return ERR_IO_PENDING;
417 case kMockWaitingJob:
418 set_load_state(LOAD_STATE_CONNECTING);
419 client_socket_factory_->WaitForSignal(this);
420 waiting_success_ = true;
421 return ERR_IO_PENDING;
422 case kMockCertErrorJob:
423 return DoConnect(false /* error */, false /* sync */,
424 true /* cert_error */);
425 case kMockPendingCertErrorJob:
426 set_load_state(LOAD_STATE_CONNECTING);
427 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
428 FROM_HERE,
429 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
430 weak_factory_.GetWeakPtr(), false /* error */,
431 true /* async */, true /* cert_error */),
432 base::TimeDelta::FromMilliseconds(2));
433 return ERR_IO_PENDING;
434 case kMockAdditionalErrorStateJob:
435 store_additional_error_state_ = true;
436 return DoConnect(false /* error */, false /* sync */,
437 false /* cert_error */);
438 case kMockPendingAdditionalErrorStateJob:
439 set_load_state(LOAD_STATE_CONNECTING);
440 store_additional_error_state_ = true;
441 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
442 FROM_HERE,
443 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
444 weak_factory_.GetWeakPtr(), false /* error */,
445 true /* async */, false /* cert_error */),
446 base::TimeDelta::FromMilliseconds(2));
447 return ERR_IO_PENDING;
448 case kMockUnreadDataJob: {
449 int ret = DoConnect(true /* successful */, false /* sync */,
450 false /* cert_error */);
451 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
452 return ret;
453 }
454 case kMockAuthChallengeOnceJob:
455 set_load_state(LOAD_STATE_CONNECTING);
456 DoAdvanceAuthChallenge(1, true /* succeed_after_last_challenge */);
457 return ERR_IO_PENDING;
458 case kMockAuthChallengeTwiceJob:
459 set_load_state(LOAD_STATE_CONNECTING);
460 DoAdvanceAuthChallenge(2, true /* succeed_after_last_challenge */);
461 return ERR_IO_PENDING;
462 case kMockAuthChallengeOnceFailingJob:
463 set_load_state(LOAD_STATE_CONNECTING);
464 DoAdvanceAuthChallenge(1, false /* succeed_after_last_challenge */);
465 return ERR_IO_PENDING;
466 case kMockAuthChallengeTwiceFailingJob:
467 set_load_state(LOAD_STATE_CONNECTING);
468 DoAdvanceAuthChallenge(2, false /* succeed_after_last_challenge */);
469 return ERR_IO_PENDING;
470 default:
471 NOTREACHED();
472 SetSocket(std::unique_ptr<StreamSocket>());
473 return ERR_FAILED;
474 }
475 }
476
ChangePriorityInternal(RequestPriority priority)477 void ChangePriorityInternal(RequestPriority priority) override {}
478
DoConnect(bool succeed,bool was_async,bool cert_error)479 int DoConnect(bool succeed, bool was_async, bool cert_error) {
480 int result = OK;
481 has_established_connection_ = true;
482 if (succeed) {
483 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
484 socket()->Connect(CompletionOnceCallback());
485 } else if (cert_error) {
486 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()));
487 result = ERR_CERT_COMMON_NAME_INVALID;
488 } else {
489 result = ERR_CONNECTION_FAILED;
490 SetSocket(std::unique_ptr<StreamSocket>());
491 }
492
493 if (was_async)
494 NotifyDelegateOfCompletion(result);
495 return result;
496 }
497
DoAdvanceAuthChallenge(int remaining_challenges,bool succeed_after_last_challenge)498 void DoAdvanceAuthChallenge(int remaining_challenges,
499 bool succeed_after_last_challenge) {
500 base::ThreadTaskRunnerHandle::Get()->PostTask(
501 FROM_HERE,
502 base::BindOnce(&TestConnectJob::InvokeNextProxyAuthCallback,
503 weak_factory_.GetWeakPtr(), remaining_challenges,
504 succeed_after_last_challenge));
505 }
506
InvokeNextProxyAuthCallback(int remaining_challenges,bool succeed_after_last_challenge)507 void InvokeNextProxyAuthCallback(int remaining_challenges,
508 bool succeed_after_last_challenge) {
509 set_load_state(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
510 if (remaining_challenges == 0) {
511 DoConnect(succeed_after_last_challenge, true /* was_async */,
512 false /* cert_error */);
513 return;
514 }
515
516 // Integration tests make sure HttpResponseInfo and HttpAuthController work.
517 // The auth tests here are just focused on ConnectJob bookkeeping.
518 HttpResponseInfo info;
519 NotifyDelegateOfProxyAuth(
520 info, nullptr /* http_auth_controller */,
521 base::BindOnce(&TestConnectJob::DoAdvanceAuthChallenge,
522 weak_factory_.GetWeakPtr(), remaining_challenges - 1,
523 succeed_after_last_challenge));
524 }
525
526 bool waiting_success_;
527 const JobType job_type_;
528 MockClientSocketFactory* const client_socket_factory_;
529 LoadState load_state_;
530 bool has_established_connection_;
531 bool store_additional_error_state_;
532
533 base::WeakPtrFactory<TestConnectJob> weak_factory_{this};
534
535 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
536 };
537
538 class TestConnectJobFactory
539 : public TransportClientSocketPool::ConnectJobFactory {
540 public:
TestConnectJobFactory(MockClientSocketFactory * client_socket_factory,NetLog * net_log)541 TestConnectJobFactory(MockClientSocketFactory* client_socket_factory,
542 NetLog* net_log)
543 : common_connect_job_params_(
544 nullptr /* client_socket_factory */,
545 nullptr /* host_resolver */,
546 nullptr /* http_auth_cache */,
547 nullptr /* http_auth_handler_factory */,
548 nullptr /* spdy_session_pool */,
549 nullptr /* quic_supported_versions */,
550 nullptr /* quic_stream_factory */,
551 nullptr /* proxy_delegate */,
552 nullptr /* http_user_agent_settings */,
553 nullptr /* ssl_client_context */,
554 nullptr /* socket_performance_watcher_factory */,
555 nullptr /* network_quality_estimator */,
556 net_log,
557 nullptr /* websocket_endpoint_lock_manager */),
558 job_type_(TestConnectJob::kMockJob),
559 job_types_(nullptr),
560 client_socket_factory_(client_socket_factory) {}
561
562 ~TestConnectJobFactory() override = default;
563
set_job_type(TestConnectJob::JobType job_type)564 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
565
set_job_types(std::list<TestConnectJob::JobType> * job_types)566 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
567 job_types_ = job_types;
568 CHECK(!job_types_->empty());
569 }
570
set_timeout_duration(base::TimeDelta timeout_duration)571 void set_timeout_duration(base::TimeDelta timeout_duration) {
572 timeout_duration_ = timeout_duration;
573 }
574
575 // ConnectJobFactory implementation.
576
NewConnectJob(ClientSocketPool::GroupId group_id,scoped_refptr<ClientSocketPool::SocketParams> socket_params,const base::Optional<NetworkTrafficAnnotationTag> & proxy_annotation_tag,RequestPriority request_priority,SocketTag socket_tag,ConnectJob::Delegate * delegate) const577 std::unique_ptr<ConnectJob> NewConnectJob(
578 ClientSocketPool::GroupId group_id,
579 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
580 const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
581 RequestPriority request_priority,
582 SocketTag socket_tag,
583 ConnectJob::Delegate* delegate) const override {
584 EXPECT_TRUE(!job_types_ || !job_types_->empty());
585 TestConnectJob::JobType job_type = job_type_;
586 if (job_types_ && !job_types_->empty()) {
587 job_type = job_types_->front();
588 job_types_->pop_front();
589 }
590 return std::make_unique<TestConnectJob>(
591 job_type, request_priority, socket_tag, timeout_duration_,
592 &common_connect_job_params_, delegate, client_socket_factory_);
593 }
594
595 private:
596 const CommonConnectJobParams common_connect_job_params_;
597 TestConnectJob::JobType job_type_;
598 std::list<TestConnectJob::JobType>* job_types_;
599 base::TimeDelta timeout_duration_;
600 MockClientSocketFactory* const client_socket_factory_;
601
602 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
603 };
604
605 } // namespace
606
607 namespace {
608
SignalJobs()609 void MockClientSocketFactory::SignalJobs() {
610 for (auto it = waiting_jobs_.begin(); it != waiting_jobs_.end(); ++it) {
611 (*it)->Signal();
612 }
613 waiting_jobs_.clear();
614 }
615
SignalJob(size_t job)616 void MockClientSocketFactory::SignalJob(size_t job) {
617 ASSERT_LT(job, waiting_jobs_.size());
618 waiting_jobs_[job]->Signal();
619 waiting_jobs_.erase(waiting_jobs_.begin() + job);
620 }
621
SetJobLoadState(size_t job,LoadState load_state)622 void MockClientSocketFactory::SetJobLoadState(size_t job,
623 LoadState load_state) {
624 ASSERT_LT(job, waiting_jobs_.size());
625 waiting_jobs_[job]->set_load_state(load_state);
626 }
627
SetJobHasEstablishedConnection(size_t job)628 void MockClientSocketFactory::SetJobHasEstablishedConnection(size_t job) {
629 ASSERT_LT(job, waiting_jobs_.size());
630 waiting_jobs_[job]->set_has_established_connection();
631 }
632
633 class ClientSocketPoolBaseTest : public TestWithTaskEnvironment {
634 protected:
ClientSocketPoolBaseTest()635 ClientSocketPoolBaseTest()
636 : TestWithTaskEnvironment(
637 base::test::TaskEnvironment::TimeSource::MOCK_TIME),
638 params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()) {
639 connect_backup_jobs_enabled_ =
640 TransportClientSocketPool::connect_backup_jobs_enabled();
641 TransportClientSocketPool::set_connect_backup_jobs_enabled(true);
642 }
643
~ClientSocketPoolBaseTest()644 ~ClientSocketPoolBaseTest() override {
645 TransportClientSocketPool::set_connect_backup_jobs_enabled(
646 connect_backup_jobs_enabled_);
647 }
648
CreatePool(int max_sockets,int max_sockets_per_group,bool enable_backup_connect_jobs=false)649 void CreatePool(int max_sockets,
650 int max_sockets_per_group,
651 bool enable_backup_connect_jobs = false) {
652 CreatePoolWithIdleTimeouts(max_sockets, max_sockets_per_group,
653 kUnusedIdleSocketTimeout,
654 ClientSocketPool::used_idle_socket_timeout(),
655 enable_backup_connect_jobs);
656 }
657
CreatePoolWithIdleTimeouts(int max_sockets,int max_sockets_per_group,base::TimeDelta unused_idle_socket_timeout,base::TimeDelta used_idle_socket_timeout,bool enable_backup_connect_jobs=false,ProxyServer proxy_server=ProxyServer::Direct ())658 void CreatePoolWithIdleTimeouts(
659 int max_sockets,
660 int max_sockets_per_group,
661 base::TimeDelta unused_idle_socket_timeout,
662 base::TimeDelta used_idle_socket_timeout,
663 bool enable_backup_connect_jobs = false,
664 ProxyServer proxy_server = ProxyServer::Direct()) {
665 DCHECK(!pool_.get());
666 std::unique_ptr<TestConnectJobFactory> connect_job_factory =
667 std::make_unique<TestConnectJobFactory>(&client_socket_factory_,
668 &net_log_);
669 connect_job_factory_ = connect_job_factory.get();
670 pool_ = TransportClientSocketPool::CreateForTesting(
671 max_sockets, max_sockets_per_group, unused_idle_socket_timeout,
672 used_idle_socket_timeout, proxy_server, std::move(connect_job_factory),
673 nullptr /* ssl_config_service */, enable_backup_connect_jobs);
674 }
675
StartRequestWithIgnoreLimits(const ClientSocketPool::GroupId & group_id,RequestPriority priority,ClientSocketPool::RespectLimits respect_limits)676 int StartRequestWithIgnoreLimits(
677 const ClientSocketPool::GroupId& group_id,
678 RequestPriority priority,
679 ClientSocketPool::RespectLimits respect_limits) {
680 return test_base_.StartRequestUsingPool(pool_.get(), group_id, priority,
681 respect_limits, params_);
682 }
683
StartRequest(const ClientSocketPool::GroupId & group_id,RequestPriority priority)684 int StartRequest(const ClientSocketPool::GroupId& group_id,
685 RequestPriority priority) {
686 return StartRequestWithIgnoreLimits(
687 group_id, priority, ClientSocketPool::RespectLimits::ENABLED);
688 }
689
GetOrderOfRequest(size_t index) const690 int GetOrderOfRequest(size_t index) const {
691 return test_base_.GetOrderOfRequest(index);
692 }
693
ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive)694 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
695 return test_base_.ReleaseOneConnection(keep_alive);
696 }
697
ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive)698 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
699 test_base_.ReleaseAllConnections(keep_alive);
700 }
701
702 // Expects a single NetLogEventType::SOCKET_POOL_CLOSING_SOCKET in |net_log_|.
703 // It should be logged for the provided source and have the indicated reason.
ExpectSocketClosedWithReason(NetLogSource expected_source,const char * expected_reason)704 void ExpectSocketClosedWithReason(NetLogSource expected_source,
705 const char* expected_reason) {
706 auto entries = net_log_.GetEntriesForSourceWithType(
707 expected_source, NetLogEventType::SOCKET_POOL_CLOSING_SOCKET,
708 NetLogEventPhase::NONE);
709 ASSERT_EQ(1u, entries.size());
710 ASSERT_TRUE(entries[0].HasParams());
711 ASSERT_TRUE(entries[0].params.is_dict());
712 const std::string* reason = entries[0].params.FindStringKey("reason");
713 ASSERT_TRUE(reason);
714 EXPECT_EQ(expected_reason, *reason);
715 }
716
request(int i)717 TestSocketRequest* request(int i) { return test_base_.request(i); }
requests_size() const718 size_t requests_size() const { return test_base_.requests_size(); }
requests()719 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
720 return test_base_.requests();
721 }
722 // Only counts the requests that get sockets asynchronously;
723 // synchronous completions are not registered by this count.
completion_count() const724 size_t completion_count() const { return test_base_.completion_count(); }
725
726 RecordingTestNetLog net_log_;
727 bool connect_backup_jobs_enabled_;
728 MockClientSocketFactory client_socket_factory_;
729 TestConnectJobFactory* connect_job_factory_;
730 // These parameters are never actually used to create a TransportConnectJob.
731 scoped_refptr<ClientSocketPool::SocketParams> params_;
732 std::unique_ptr<TransportClientSocketPool> pool_;
733 ClientSocketPoolTest test_base_;
734 };
735
736 // TODO(950069): Add testing for frame_origin in NetworkIsolationKey
737 // using kAppendInitiatingFrameOriginToNetworkIsolationKey.
738
TEST_F(ClientSocketPoolBaseTest,BasicSynchronous)739 TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
740 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
741
742 TestCompletionCallback callback;
743 ClientSocketHandle handle;
744 RecordingBoundTestNetLog log;
745 TestLoadTimingInfoNotConnected(handle);
746
747 EXPECT_EQ(OK, handle.Init(
748 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
749 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
750 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
751 pool_.get(), log.bound()));
752 EXPECT_TRUE(handle.is_initialized());
753 EXPECT_TRUE(handle.socket());
754 TestLoadTimingInfoConnectedNotReused(handle);
755
756 handle.Reset();
757 TestLoadTimingInfoNotConnected(handle);
758
759 auto entries = log.GetEntries();
760
761 EXPECT_EQ(5u, entries.size());
762 EXPECT_TRUE(LogContainsEvent(
763 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
764 NetLogEventPhase::NONE));
765 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
766 EXPECT_TRUE(LogContainsEvent(
767 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
768 NetLogEventPhase::NONE));
769 EXPECT_TRUE(LogContainsEvent(entries, 3,
770 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
771 NetLogEventPhase::NONE));
772 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
773 }
774
TEST_F(ClientSocketPoolBaseTest,InitConnectionFailure)775 TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
776 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
777
778 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
779 RecordingBoundTestNetLog log;
780
781 ClientSocketHandle handle;
782 TestCompletionCallback callback;
783 // Set the additional error state members to ensure that they get cleared.
784 handle.set_is_ssl_error(true);
785 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
786 EXPECT_EQ(
787 ERR_CONNECTION_FAILED,
788 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
789 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
790 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
791 pool_.get(), log.bound()));
792 EXPECT_FALSE(handle.socket());
793 EXPECT_FALSE(handle.is_ssl_error());
794 EXPECT_FALSE(handle.ssl_cert_request_info());
795 TestLoadTimingInfoNotConnected(handle);
796
797 auto entries = log.GetEntries();
798
799 EXPECT_EQ(4u, entries.size());
800 EXPECT_TRUE(LogContainsEvent(
801 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
802 NetLogEventPhase::NONE));
803 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
804 EXPECT_TRUE(LogContainsEvent(
805 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
806 NetLogEventPhase::NONE));
807 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
808 }
809
810 // Test releasing an open socket into the socket pool, telling the socket pool
811 // to close the socket.
TEST_F(ClientSocketPoolBaseTest,ReleaseAndCloseConnection)812 TEST_F(ClientSocketPoolBaseTest, ReleaseAndCloseConnection) {
813 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
814
815 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
816 ASSERT_TRUE(request(0)->handle()->socket());
817 net::NetLogSource source = request(0)->handle()->socket()->NetLog().source();
818 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
819
820 EXPECT_EQ(0, pool_->IdleSocketCount());
821 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
822
823 ExpectSocketClosedWithReason(
824 source, TransportClientSocketPool::kClosedConnectionReturnedToPool);
825 }
826
TEST_F(ClientSocketPoolBaseTest,SocketWithUnreadDataReturnedToPool)827 TEST_F(ClientSocketPoolBaseTest, SocketWithUnreadDataReturnedToPool) {
828 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
829 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
830
831 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
832 ASSERT_TRUE(request(0)->handle()->socket());
833 net::NetLogSource source = request(0)->handle()->socket()->NetLog().source();
834 EXPECT_TRUE(request(0)->handle()->socket()->IsConnected());
835 EXPECT_FALSE(request(0)->handle()->socket()->IsConnectedAndIdle());
836 ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE);
837
838 EXPECT_EQ(0, pool_->IdleSocketCount());
839 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
840
841 ExpectSocketClosedWithReason(
842 source, TransportClientSocketPool::kDataReceivedUnexpectedly);
843 }
844
845 // Make sure different groups do not share sockets.
TEST_F(ClientSocketPoolBaseTest,GroupSeparation)846 TEST_F(ClientSocketPoolBaseTest, GroupSeparation) {
847 base::test::ScopedFeatureList feature_list;
848 feature_list.InitAndEnableFeature(
849 features::kPartitionConnectionsByNetworkIsolationKey);
850
851 CreatePool(1000 /* max_sockets */, 2 /* max_sockets_per_group */);
852
853 const HostPortPair kHostPortPairs[] = {
854 {"a", 80},
855 {"a", 443},
856 {"b", 80},
857 };
858
859 const ClientSocketPool::SocketType kSocketTypes[] = {
860 ClientSocketPool::SocketType::kHttp,
861 ClientSocketPool::SocketType::kSsl,
862 };
863
864 const PrivacyMode kPrivacyModes[] = {PrivacyMode::PRIVACY_MODE_DISABLED,
865 PrivacyMode::PRIVACY_MODE_ENABLED};
866
867 const auto kOriginA = url::Origin::Create(GURL("http://a.test/"));
868 const auto kOriginB = url::Origin::Create(GURL("http://b.test/"));
869 const NetworkIsolationKey kNetworkIsolationKeys[] = {
870 NetworkIsolationKey(kOriginA, kOriginA),
871 NetworkIsolationKey(kOriginB, kOriginB),
872 };
873
874 const bool kDisableSecureDnsValues[] = {false, true};
875
876 int total_idle_sockets = 0;
877
878 // Walk through each GroupId, making sure that requesting a socket for one
879 // group does not return a previously connected socket for another group.
880 for (const auto& host_port_pair : kHostPortPairs) {
881 SCOPED_TRACE(host_port_pair.ToString());
882 for (const auto& socket_type : kSocketTypes) {
883 SCOPED_TRACE(static_cast<int>(socket_type));
884 for (const auto& privacy_mode : kPrivacyModes) {
885 SCOPED_TRACE(privacy_mode);
886 for (const auto& network_isolation_key : kNetworkIsolationKeys) {
887 SCOPED_TRACE(network_isolation_key.ToString());
888 for (const auto& disable_secure_dns : kDisableSecureDnsValues) {
889 SCOPED_TRACE(disable_secure_dns);
890
891 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
892
893 ClientSocketPool::GroupId group_id(
894 host_port_pair, socket_type, privacy_mode,
895 network_isolation_key, disable_secure_dns);
896
897 EXPECT_FALSE(pool_->HasGroupForTesting(group_id));
898
899 TestCompletionCallback callback;
900 ClientSocketHandle handle;
901
902 // Since the group is empty, requesting a socket should not complete
903 // synchronously.
904 EXPECT_THAT(handle.Init(group_id, params_, base::nullopt,
905 DEFAULT_PRIORITY, SocketTag(),
906 ClientSocketPool::RespectLimits::ENABLED,
907 callback.callback(),
908 ClientSocketPool::ProxyAuthCallback(),
909 pool_.get(), NetLogWithSource()),
910 IsError(ERR_IO_PENDING));
911 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
912 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
913
914 EXPECT_THAT(callback.WaitForResult(), IsOk());
915 EXPECT_TRUE(handle.socket());
916 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
917 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
918
919 // Return socket to pool.
920 handle.Reset();
921 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
922
923 // Requesting a socket again should return the same socket as
924 // before, so should complete synchronously.
925 EXPECT_THAT(handle.Init(group_id, params_, base::nullopt,
926 DEFAULT_PRIORITY, SocketTag(),
927 ClientSocketPool::RespectLimits::ENABLED,
928 callback.callback(),
929 ClientSocketPool::ProxyAuthCallback(),
930 pool_.get(), NetLogWithSource()),
931 IsOk());
932 EXPECT_TRUE(handle.socket());
933 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
934
935 // Return socket to pool again.
936 handle.Reset();
937 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
938
939 ++total_idle_sockets;
940 }
941 }
942 }
943 }
944 }
945 }
946
TEST_F(ClientSocketPoolBaseTest,TotalLimit)947 TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
948 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
949
950 // TODO(eroman): Check that the NetLog contains this event.
951
952 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
953 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
954 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
955 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY), IsOk());
956
957 EXPECT_EQ(static_cast<int>(requests_size()),
958 client_socket_factory_.allocation_count());
959 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
960
961 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
962 IsError(ERR_IO_PENDING));
963 EXPECT_THAT(StartRequest(TestGroupId("f"), DEFAULT_PRIORITY),
964 IsError(ERR_IO_PENDING));
965 EXPECT_THAT(StartRequest(TestGroupId("g"), DEFAULT_PRIORITY),
966 IsError(ERR_IO_PENDING));
967
968 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
969
970 EXPECT_EQ(static_cast<int>(requests_size()),
971 client_socket_factory_.allocation_count());
972 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
973
974 EXPECT_EQ(1, GetOrderOfRequest(1));
975 EXPECT_EQ(2, GetOrderOfRequest(2));
976 EXPECT_EQ(3, GetOrderOfRequest(3));
977 EXPECT_EQ(4, GetOrderOfRequest(4));
978 EXPECT_EQ(5, GetOrderOfRequest(5));
979 EXPECT_EQ(6, GetOrderOfRequest(6));
980 EXPECT_EQ(7, GetOrderOfRequest(7));
981
982 // Make sure we test order of all requests made.
983 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
984 }
985
TEST_F(ClientSocketPoolBaseTest,TotalLimitReachedNewGroup)986 TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
987 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
988
989 // TODO(eroman): Check that the NetLog contains this event.
990
991 // Reach all limits: max total sockets, and max sockets per group.
992 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
993 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
994 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
995 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
996
997 EXPECT_EQ(static_cast<int>(requests_size()),
998 client_socket_factory_.allocation_count());
999 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
1000
1001 // Now create a new group and verify that we don't starve it.
1002 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1003 IsError(ERR_IO_PENDING));
1004
1005 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1006
1007 EXPECT_EQ(static_cast<int>(requests_size()),
1008 client_socket_factory_.allocation_count());
1009 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
1010
1011 EXPECT_EQ(1, GetOrderOfRequest(1));
1012 EXPECT_EQ(2, GetOrderOfRequest(2));
1013 EXPECT_EQ(3, GetOrderOfRequest(3));
1014 EXPECT_EQ(4, GetOrderOfRequest(4));
1015 EXPECT_EQ(5, GetOrderOfRequest(5));
1016
1017 // Make sure we test order of all requests made.
1018 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
1019 }
1020
TEST_F(ClientSocketPoolBaseTest,TotalLimitRespectsPriority)1021 TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
1022 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1023
1024 EXPECT_THAT(StartRequest(TestGroupId("b"), LOWEST), IsOk());
1025 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsOk());
1026 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1027 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
1028
1029 EXPECT_EQ(static_cast<int>(requests_size()),
1030 client_socket_factory_.allocation_count());
1031
1032 EXPECT_THAT(StartRequest(TestGroupId("c"), LOWEST), IsError(ERR_IO_PENDING));
1033 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1034 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
1035
1036 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1037
1038 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
1039
1040 // First 4 requests don't have to wait, and finish in order.
1041 EXPECT_EQ(1, GetOrderOfRequest(1));
1042 EXPECT_EQ(2, GetOrderOfRequest(2));
1043 EXPECT_EQ(3, GetOrderOfRequest(3));
1044 EXPECT_EQ(4, GetOrderOfRequest(4));
1045
1046 // Request ("b", HIGHEST) has the highest priority, then (TestGroupId("a"),
1047 // MEDIUM), and then ("c", LOWEST).
1048 EXPECT_EQ(7, GetOrderOfRequest(5));
1049 EXPECT_EQ(6, GetOrderOfRequest(6));
1050 EXPECT_EQ(5, GetOrderOfRequest(7));
1051
1052 // Make sure we test order of all requests made.
1053 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
1054 }
1055
1056 // Test reprioritizing a request before completion doesn't interfere with
1057 // its completion.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeOne)1058 TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
1059 CreatePool(kDefaultMaxSockets, 1);
1060
1061 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1062 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1063 EXPECT_TRUE(request(0)->handle()->socket());
1064 EXPECT_FALSE(request(1)->handle()->socket());
1065
1066 request(1)->handle()->SetPriority(HIGHEST);
1067
1068 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1069
1070 EXPECT_TRUE(request(1)->handle()->socket());
1071 }
1072
1073 // Reprioritize a request up past another one and make sure that changes the
1074 // completion order.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeUpReorder)1075 TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1076 CreatePool(kDefaultMaxSockets, 1);
1077
1078 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1079 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1080 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1081 EXPECT_TRUE(request(0)->handle()->socket());
1082 EXPECT_FALSE(request(1)->handle()->socket());
1083 EXPECT_FALSE(request(2)->handle()->socket());
1084
1085 request(2)->handle()->SetPriority(HIGHEST);
1086
1087 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1088
1089 EXPECT_EQ(1, GetOrderOfRequest(1));
1090 EXPECT_EQ(3, GetOrderOfRequest(2));
1091 EXPECT_EQ(2, GetOrderOfRequest(3));
1092 }
1093
1094 // Reprioritize a request without changing relative priorities and check
1095 // that the order doesn't change.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeUpNoReorder)1096 TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1097 CreatePool(kDefaultMaxSockets, 1);
1098
1099 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1100 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1101 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1102 EXPECT_TRUE(request(0)->handle()->socket());
1103 EXPECT_FALSE(request(1)->handle()->socket());
1104 EXPECT_FALSE(request(2)->handle()->socket());
1105
1106 request(2)->handle()->SetPriority(MEDIUM);
1107
1108 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1109
1110 EXPECT_EQ(1, GetOrderOfRequest(1));
1111 EXPECT_EQ(2, GetOrderOfRequest(2));
1112 EXPECT_EQ(3, GetOrderOfRequest(3));
1113 }
1114
1115 // Reprioritize a request past down another one and make sure that changes the
1116 // completion order.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeDownReorder)1117 TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1118 CreatePool(kDefaultMaxSockets, 1);
1119
1120 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1121 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1122 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1123 EXPECT_TRUE(request(0)->handle()->socket());
1124 EXPECT_FALSE(request(1)->handle()->socket());
1125 EXPECT_FALSE(request(2)->handle()->socket());
1126
1127 request(1)->handle()->SetPriority(LOW);
1128
1129 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1130
1131 EXPECT_EQ(1, GetOrderOfRequest(1));
1132 EXPECT_EQ(3, GetOrderOfRequest(2));
1133 EXPECT_EQ(2, GetOrderOfRequest(3));
1134 }
1135
1136 // Reprioritize a request to the same level as another and confirm it is
1137 // put after the old request.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeResetFIFO)1138 TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1139 CreatePool(kDefaultMaxSockets, 1);
1140
1141 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1142 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1143 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1144 EXPECT_TRUE(request(0)->handle()->socket());
1145 EXPECT_FALSE(request(1)->handle()->socket());
1146 EXPECT_FALSE(request(2)->handle()->socket());
1147
1148 request(1)->handle()->SetPriority(MEDIUM);
1149
1150 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1151
1152 EXPECT_EQ(1, GetOrderOfRequest(1));
1153 EXPECT_EQ(3, GetOrderOfRequest(2));
1154 EXPECT_EQ(2, GetOrderOfRequest(3));
1155 }
1156
TEST_F(ClientSocketPoolBaseTest,TotalLimitRespectsGroupLimit)1157 TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1158 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1159
1160 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
1161 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsOk());
1162 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1163 EXPECT_THAT(StartRequest(TestGroupId("b"), MEDIUM), IsOk());
1164
1165 EXPECT_EQ(static_cast<int>(requests_size()),
1166 client_socket_factory_.allocation_count());
1167
1168 EXPECT_THAT(StartRequest(TestGroupId("c"), MEDIUM), IsError(ERR_IO_PENDING));
1169 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1170 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
1171
1172 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1173
1174 EXPECT_EQ(static_cast<int>(requests_size()),
1175 client_socket_factory_.allocation_count());
1176 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
1177
1178 // First 4 requests don't have to wait, and finish in order.
1179 EXPECT_EQ(1, GetOrderOfRequest(1));
1180 EXPECT_EQ(2, GetOrderOfRequest(2));
1181 EXPECT_EQ(3, GetOrderOfRequest(3));
1182 EXPECT_EQ(4, GetOrderOfRequest(4));
1183
1184 // Request ("b", 7) has the highest priority, but we can't make new socket for
1185 // group "b", because it has reached the per-group limit. Then we make
1186 // socket for ("c", 6), because it has higher priority than ("a", 4),
1187 // and we still can't make a socket for group "b".
1188 EXPECT_EQ(5, GetOrderOfRequest(5));
1189 EXPECT_EQ(6, GetOrderOfRequest(6));
1190 EXPECT_EQ(7, GetOrderOfRequest(7));
1191
1192 // Make sure we test order of all requests made.
1193 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1194 }
1195
1196 // Make sure that we count connecting sockets against the total limit.
TEST_F(ClientSocketPoolBaseTest,TotalLimitCountsConnectingSockets)1197 TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1198 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1199
1200 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1201 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
1202 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
1203
1204 // Create one asynchronous request.
1205 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1206 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY),
1207 IsError(ERR_IO_PENDING));
1208
1209 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1210 // actually become pending until 2ms after they have been created. In order
1211 // to flush all tasks, we need to wait so that we know there are no
1212 // soon-to-be-pending tasks waiting.
1213 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
1214
1215 // The next synchronous request should wait for its turn.
1216 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1217 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
1218 IsError(ERR_IO_PENDING));
1219
1220 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1221
1222 EXPECT_EQ(static_cast<int>(requests_size()),
1223 client_socket_factory_.allocation_count());
1224
1225 EXPECT_EQ(1, GetOrderOfRequest(1));
1226 EXPECT_EQ(2, GetOrderOfRequest(2));
1227 EXPECT_EQ(3, GetOrderOfRequest(3));
1228 EXPECT_EQ(4, GetOrderOfRequest(4));
1229 EXPECT_EQ(5, GetOrderOfRequest(5));
1230
1231 // Make sure we test order of all requests made.
1232 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
1233 }
1234
TEST_F(ClientSocketPoolBaseTest,CorrectlyCountStalledGroups)1235 TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1236 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1237 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1238
1239 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1240 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1241 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1242 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1243
1244 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1245
1246 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1247
1248 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY),
1249 IsError(ERR_IO_PENDING));
1250 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1251 IsError(ERR_IO_PENDING));
1252
1253 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1254
1255 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1256 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1257 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1258 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1259 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1260 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1261 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1262 }
1263
TEST_F(ClientSocketPoolBaseTest,StallAndThenCancelAndTriggerAvailableSocket)1264 TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1265 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1266 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1267
1268 ClientSocketHandle handle;
1269 TestCompletionCallback callback;
1270 EXPECT_EQ(
1271 ERR_IO_PENDING,
1272 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1273 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1274 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1275 pool_.get(), NetLogWithSource()));
1276
1277 ClientSocketHandle handles[4];
1278 for (size_t i = 0; i < base::size(handles); ++i) {
1279 TestCompletionCallback callback;
1280 EXPECT_EQ(ERR_IO_PENDING,
1281 handles[i].Init(
1282 TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
1283 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1284 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1285 pool_.get(), NetLogWithSource()));
1286 }
1287
1288 // One will be stalled, cancel all the handles now.
1289 // This should hit the OnAvailableSocketSlot() code where we previously had
1290 // stalled groups, but no longer have any.
1291 for (size_t i = 0; i < base::size(handles); ++i)
1292 handles[i].Reset();
1293 }
1294
TEST_F(ClientSocketPoolBaseTest,CancelStalledSocketAtSocketLimit)1295 TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
1296 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1297 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1298
1299 {
1300 ClientSocketHandle handles[kDefaultMaxSockets];
1301 TestCompletionCallback callbacks[kDefaultMaxSockets];
1302 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1303 EXPECT_EQ(OK,
1304 handles[i].Init(TestGroupId(base::NumberToString(i)), params_,
1305 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1306 ClientSocketPool::RespectLimits::ENABLED,
1307 callbacks[i].callback(),
1308 ClientSocketPool::ProxyAuthCallback(),
1309 pool_.get(), NetLogWithSource()));
1310 }
1311
1312 // Force a stalled group.
1313 ClientSocketHandle stalled_handle;
1314 TestCompletionCallback callback;
1315 EXPECT_EQ(ERR_IO_PENDING,
1316 stalled_handle.Init(
1317 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1318 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1319 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1320 pool_.get(), NetLogWithSource()));
1321
1322 // Cancel the stalled request.
1323 stalled_handle.Reset();
1324
1325 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1326 EXPECT_EQ(0, pool_->IdleSocketCount());
1327
1328 // Dropping out of scope will close all handles and return them to idle.
1329 }
1330
1331 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1332 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
1333 }
1334
TEST_F(ClientSocketPoolBaseTest,CancelPendingSocketAtSocketLimit)1335 TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1336 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1337 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1338
1339 {
1340 ClientSocketHandle handles[kDefaultMaxSockets];
1341 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1342 TestCompletionCallback callback;
1343 EXPECT_EQ(ERR_IO_PENDING,
1344 handles[i].Init(TestGroupId(base::NumberToString(i)), params_,
1345 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1346 ClientSocketPool::RespectLimits::ENABLED,
1347 callback.callback(),
1348 ClientSocketPool::ProxyAuthCallback(),
1349 pool_.get(), NetLogWithSource()));
1350 }
1351
1352 // Force a stalled group.
1353 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1354 ClientSocketHandle stalled_handle;
1355 TestCompletionCallback callback;
1356 EXPECT_EQ(ERR_IO_PENDING,
1357 stalled_handle.Init(
1358 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1359 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1360 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1361 pool_.get(), NetLogWithSource()));
1362
1363 // Since it is stalled, it should have no connect jobs.
1364 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1365 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1366 TestGroupId("foo")));
1367 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1368 TestGroupId("foo")));
1369
1370 // Cancel the stalled request.
1371 handles[0].Reset();
1372
1373 // Now we should have a connect job.
1374 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1375 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1376 TestGroupId("foo")));
1377 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1378 TestGroupId("foo")));
1379
1380 // The stalled socket should connect.
1381 EXPECT_THAT(callback.WaitForResult(), IsOk());
1382
1383 EXPECT_EQ(kDefaultMaxSockets + 1,
1384 client_socket_factory_.allocation_count());
1385 EXPECT_EQ(0, pool_->IdleSocketCount());
1386 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1387 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1388 TestGroupId("foo")));
1389 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1390 TestGroupId("foo")));
1391
1392 // Dropping out of scope will close all handles and return them to idle.
1393 }
1394
1395 EXPECT_EQ(1, pool_->IdleSocketCount());
1396 }
1397
TEST_F(ClientSocketPoolBaseTest,WaitForStalledSocketAtSocketLimit)1398 TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1399 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1400 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1401
1402 ClientSocketHandle stalled_handle;
1403 TestCompletionCallback callback;
1404 {
1405 EXPECT_FALSE(pool_->IsStalled());
1406 ClientSocketHandle handles[kDefaultMaxSockets];
1407 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1408 TestCompletionCallback callback;
1409 EXPECT_EQ(
1410 OK, handles[i].Init(
1411 TestGroupId(base::StringPrintf("Take 2: %d", i)), params_,
1412 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1413 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1414 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1415 NetLogWithSource()));
1416 }
1417
1418 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1419 EXPECT_EQ(0, pool_->IdleSocketCount());
1420 EXPECT_FALSE(pool_->IsStalled());
1421
1422 // Now we will hit the socket limit.
1423 EXPECT_EQ(ERR_IO_PENDING,
1424 stalled_handle.Init(
1425 TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY,
1426 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1427 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1428 pool_.get(), NetLogWithSource()));
1429 EXPECT_TRUE(pool_->IsStalled());
1430
1431 // Dropping out of scope will close all handles and return them to idle.
1432 }
1433
1434 // But if we wait for it, the released idle sockets will be closed in
1435 // preference of the waiting request.
1436 EXPECT_THAT(callback.WaitForResult(), IsOk());
1437
1438 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1439 EXPECT_EQ(3, pool_->IdleSocketCount());
1440 }
1441
1442 // Regression test for http://crbug.com/40952.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketAtSocketLimitDeleteGroup)1443 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1444 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1445 true /* enable_backup_connect_jobs */);
1446 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1447
1448 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1449 ClientSocketHandle handle;
1450 TestCompletionCallback callback;
1451 EXPECT_EQ(OK, handle.Init(TestGroupId(base::NumberToString(i)), params_,
1452 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1453 ClientSocketPool::RespectLimits::ENABLED,
1454 callback.callback(),
1455 ClientSocketPool::ProxyAuthCallback(),
1456 pool_.get(), NetLogWithSource()));
1457 }
1458
1459 // Flush all the DoReleaseSocket tasks.
1460 base::RunLoop().RunUntilIdle();
1461
1462 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1463 // reuse a socket.
1464 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1465 ClientSocketHandle handle;
1466 TestCompletionCallback callback;
1467
1468 // "0" is special here, since it should be the first entry in the sorted map,
1469 // which is the one which we would close an idle socket for. We shouldn't
1470 // close an idle socket though, since we should reuse the idle socket.
1471 EXPECT_EQ(OK, handle.Init(
1472 TestGroupId("0"), params_, base::nullopt, DEFAULT_PRIORITY,
1473 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1474 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1475 pool_.get(), NetLogWithSource()));
1476
1477 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1478 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1479 }
1480
TEST_F(ClientSocketPoolBaseTest,PendingRequests)1481 TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
1482 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1483
1484 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1485 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1486 EXPECT_THAT(StartRequest(TestGroupId("a"), IDLE), IsError(ERR_IO_PENDING));
1487 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1488 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1489 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1490 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1491 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1492
1493 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1494 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1495 client_socket_factory_.allocation_count());
1496 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1497 completion_count());
1498
1499 EXPECT_EQ(1, GetOrderOfRequest(1));
1500 EXPECT_EQ(2, GetOrderOfRequest(2));
1501 EXPECT_EQ(8, GetOrderOfRequest(3));
1502 EXPECT_EQ(6, GetOrderOfRequest(4));
1503 EXPECT_EQ(4, GetOrderOfRequest(5));
1504 EXPECT_EQ(3, GetOrderOfRequest(6));
1505 EXPECT_EQ(5, GetOrderOfRequest(7));
1506 EXPECT_EQ(7, GetOrderOfRequest(8));
1507
1508 // Make sure we test order of all requests made.
1509 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
1510 }
1511
TEST_F(ClientSocketPoolBaseTest,PendingRequests_NoKeepAlive)1512 TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
1513 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1514
1515 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1516 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1517 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1518 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1519 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1520 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1521 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1522
1523 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1524
1525 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1526 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
1527
1528 EXPECT_EQ(static_cast<int>(requests_size()),
1529 client_socket_factory_.allocation_count());
1530 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1531 completion_count());
1532 }
1533
TEST_F(ClientSocketPoolBaseTest,ResetAndCloseSocket)1534 TEST_F(ClientSocketPoolBaseTest, ResetAndCloseSocket) {
1535 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1536
1537 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1538 ClientSocketHandle handle;
1539 TestCompletionCallback callback;
1540 EXPECT_EQ(
1541 ERR_IO_PENDING,
1542 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1543 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1544 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1545 pool_.get(), NetLogWithSource()));
1546
1547 EXPECT_THAT(callback.WaitForResult(), IsOk());
1548 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1549 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1550 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
1551 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1552
1553 handle.ResetAndCloseSocket();
1554 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1555 }
1556
1557 // This test will start up a socket request and then call Reset() on the handle.
1558 // The pending ConnectJob should not be destroyed.
TEST_F(ClientSocketPoolBaseTest,CancelRequestKeepsConnectJob)1559 TEST_F(ClientSocketPoolBaseTest, CancelRequestKeepsConnectJob) {
1560 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1561
1562 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1563 ClientSocketHandle handle;
1564 TestCompletionCallback callback;
1565 EXPECT_EQ(
1566 ERR_IO_PENDING,
1567 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1568 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1569 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1570 pool_.get(), NetLogWithSource()));
1571 handle.Reset();
1572 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1573 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1574 }
1575
1576 // This test will start up a socket request and then call ResetAndCloseSocket()
1577 // on the handle. The pending ConnectJob or connected socket should be
1578 // destroyed.
TEST_F(ClientSocketPoolBaseTest,CancelRequestAndCloseSocket)1579 TEST_F(ClientSocketPoolBaseTest, CancelRequestAndCloseSocket) {
1580 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1581
1582 // When true, the socket connects before it's canceled.
1583 for (bool cancel_when_callback_pending : {false, true}) {
1584 if (cancel_when_callback_pending) {
1585 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1586 } else {
1587 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1588 }
1589 ClientSocketHandle handle;
1590 TestCompletionCallback callback;
1591 EXPECT_EQ(
1592 ERR_IO_PENDING,
1593 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1594 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1595 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1596 pool_.get(), NetLogWithSource()));
1597 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1598 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1599
1600 if (cancel_when_callback_pending) {
1601 client_socket_factory_.SignalJobs();
1602 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1603 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1604 }
1605
1606 handle.ResetAndCloseSocket();
1607 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1608 }
1609 }
1610
TEST_F(ClientSocketPoolBaseTest,CancelRequestAndCloseSocketWhenMoreRequestsThanConnectJobs)1611 TEST_F(ClientSocketPoolBaseTest,
1612 CancelRequestAndCloseSocketWhenMoreRequestsThanConnectJobs) {
1613 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1614
1615 // When true, the sockets connect before they're canceled.
1616 for (bool cancel_when_callback_pending : {false, true}) {
1617 if (cancel_when_callback_pending) {
1618 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1619 } else {
1620 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1621 }
1622
1623 std::vector<std::unique_ptr<ClientSocketHandle>> handles;
1624 TestCompletionCallback callback;
1625 // Make |kDefaultMaxSockets + 1| socket requests.
1626 for (int i = 0; i < kDefaultMaxSocketsPerGroup + 1; ++i) {
1627 std::unique_ptr<ClientSocketHandle> handle =
1628 std::make_unique<ClientSocketHandle>();
1629 EXPECT_EQ(ERR_IO_PENDING,
1630 handle->Init(
1631 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1632 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1633 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1634 pool_.get(), NetLogWithSource()));
1635 handles.push_back(std::move(handle));
1636 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1637 EXPECT_EQ(
1638 static_cast<size_t>(std::min(i + 1, kDefaultMaxSocketsPerGroup)),
1639 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1640 }
1641
1642 if (cancel_when_callback_pending) {
1643 client_socket_factory_.SignalJobs();
1644 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1645 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1646 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1647 }
1648
1649 // Calling ResetAndCloseSocket() on a handle should not cancel a ConnectJob
1650 // or close a socket, since there are more requests than ConnectJobs or
1651 // sockets.
1652 handles[kDefaultMaxSocketsPerGroup]->ResetAndCloseSocket();
1653 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1654 if (cancel_when_callback_pending) {
1655 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1656 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1657 } else {
1658 EXPECT_EQ(static_cast<size_t>(kDefaultMaxSocketsPerGroup),
1659 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1660 }
1661
1662 // Calling ResetAndCloseSocket() on other handles should cancel a ConnectJob
1663 // or close a socket.
1664 for (int i = kDefaultMaxSocketsPerGroup - 1; i >= 0; --i) {
1665 handles[i]->ResetAndCloseSocket();
1666 if (i > 0) {
1667 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1668 if (cancel_when_callback_pending) {
1669 EXPECT_EQ(i,
1670 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1671 } else {
1672 EXPECT_EQ(static_cast<size_t>(i),
1673 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1674 }
1675 } else {
1676 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1677 }
1678 }
1679 }
1680 }
1681
TEST_F(ClientSocketPoolBaseTest,ConnectCancelConnect)1682 TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
1683 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1684
1685 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1686 ClientSocketHandle handle;
1687 TestCompletionCallback callback;
1688
1689 EXPECT_EQ(
1690 ERR_IO_PENDING,
1691 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1692 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1693 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1694 pool_.get(), NetLogWithSource()));
1695
1696 handle.Reset();
1697 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1698 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1699
1700 // This will create a second ConnectJob, since the other ConnectJob was
1701 // previously assigned to a request.
1702 TestCompletionCallback callback2;
1703 EXPECT_EQ(
1704 ERR_IO_PENDING,
1705 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1706 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1707 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
1708 pool_.get(), NetLogWithSource()));
1709
1710 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1711 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1712
1713 EXPECT_THAT(callback2.WaitForResult(), IsOk());
1714 EXPECT_FALSE(callback.have_result());
1715 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1716 // One ConnectJob completed, and its socket is now assigned to |handle|.
1717 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1718 // The other ConnectJob should have either completed, or still be connecting.
1719 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1720 pool_->IdleSocketCountInGroup(TestGroupId("a")));
1721
1722 handle.Reset();
1723 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1724 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1725 pool_->IdleSocketCountInGroup(TestGroupId("a")));
1726 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1727 }
1728
TEST_F(ClientSocketPoolBaseTest,CancelRequest)1729 TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
1730 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1731
1732 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1733 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1734 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1735 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1736 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1737 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1738 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1739
1740 // Cancel a request.
1741 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
1742 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1743 (*requests())[index_to_cancel]->handle()->Reset();
1744
1745 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1746
1747 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1748 client_socket_factory_.allocation_count());
1749 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1750 completion_count());
1751
1752 EXPECT_EQ(1, GetOrderOfRequest(1));
1753 EXPECT_EQ(2, GetOrderOfRequest(2));
1754 EXPECT_EQ(5, GetOrderOfRequest(3));
1755 EXPECT_EQ(3, GetOrderOfRequest(4));
1756 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1757 GetOrderOfRequest(5)); // Canceled request.
1758 EXPECT_EQ(4, GetOrderOfRequest(6));
1759 EXPECT_EQ(6, GetOrderOfRequest(7));
1760
1761 // Make sure we test order of all requests made.
1762 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1763 }
1764
1765 // Function to be used as a callback on socket request completion. It first
1766 // disconnects the successfully connected socket from the first request, and
1767 // then reuses the ClientSocketHandle to request another socket.
1768 //
1769 // |nested_callback| is called with the result of the second socket request.
RequestSocketOnComplete(ClientSocketHandle * handle,TransportClientSocketPool * pool,TestConnectJobFactory * test_connect_job_factory,TestConnectJob::JobType next_job_type,TestCompletionCallback * nested_callback,int first_request_result)1770 void RequestSocketOnComplete(ClientSocketHandle* handle,
1771 TransportClientSocketPool* pool,
1772 TestConnectJobFactory* test_connect_job_factory,
1773 TestConnectJob::JobType next_job_type,
1774 TestCompletionCallback* nested_callback,
1775 int first_request_result) {
1776 EXPECT_THAT(first_request_result, IsOk());
1777
1778 test_connect_job_factory->set_job_type(next_job_type);
1779
1780 // Don't allow reuse of the socket. Disconnect it and then release it.
1781 if (handle->socket())
1782 handle->socket()->Disconnect();
1783 handle->Reset();
1784
1785 TestCompletionCallback callback;
1786 int rv = handle->Init(
1787 TestGroupId("a"),
1788 ClientSocketPool::SocketParams::CreateForHttpForTesting(), base::nullopt,
1789 LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1790 nested_callback->callback(), ClientSocketPool::ProxyAuthCallback(), pool,
1791 NetLogWithSource());
1792 if (rv != ERR_IO_PENDING) {
1793 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
1794 nested_callback->callback().Run(rv);
1795 } else {
1796 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
1797 }
1798 }
1799
1800 // Tests the case where a second socket is requested in a completion callback,
1801 // and the second socket connects asynchronously. Reuses the same
1802 // ClientSocketHandle for the second socket, after disconnecting the first.
TEST_F(ClientSocketPoolBaseTest,RequestPendingJobTwice)1803 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
1804 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1805
1806 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1807 ClientSocketHandle handle;
1808 TestCompletionCallback second_result_callback;
1809 int rv = handle.Init(
1810 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1811 ClientSocketPool::RespectLimits::ENABLED,
1812 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1813 connect_job_factory_, TestConnectJob::kMockPendingJob,
1814 &second_result_callback),
1815 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
1816 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1817
1818 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
1819 }
1820
1821 // Tests the case where a second socket is requested in a completion callback,
1822 // and the second socket connects synchronously. Reuses the same
1823 // ClientSocketHandle for the second socket, after disconnecting the first.
TEST_F(ClientSocketPoolBaseTest,RequestPendingJobThenSynchronous)1824 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
1825 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1826
1827 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1828 ClientSocketHandle handle;
1829 TestCompletionCallback second_result_callback;
1830 int rv = handle.Init(
1831 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1832 ClientSocketPool::RespectLimits::ENABLED,
1833 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1834 connect_job_factory_, TestConnectJob::kMockPendingJob,
1835 &second_result_callback),
1836 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
1837 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1838
1839 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
1840 }
1841
1842 // Make sure that pending requests get serviced after active requests get
1843 // cancelled.
TEST_F(ClientSocketPoolBaseTest,CancelActiveRequestWithPendingRequests)1844 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
1845 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1846
1847 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1848
1849 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1850 IsError(ERR_IO_PENDING));
1851 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1852 IsError(ERR_IO_PENDING));
1853 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1854 IsError(ERR_IO_PENDING));
1855 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1856 IsError(ERR_IO_PENDING));
1857 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1858 IsError(ERR_IO_PENDING));
1859 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1860 IsError(ERR_IO_PENDING));
1861 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1862 IsError(ERR_IO_PENDING));
1863
1864 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1865 // Let's cancel them.
1866 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
1867 ASSERT_FALSE(request(i)->handle()->is_initialized());
1868 request(i)->handle()->Reset();
1869 }
1870
1871 // Let's wait for the rest to complete now.
1872 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1873 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
1874 request(i)->handle()->Reset();
1875 }
1876
1877 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1878 completion_count());
1879 }
1880
1881 // Make sure that pending requests get serviced after active requests fail.
TEST_F(ClientSocketPoolBaseTest,FailingActiveRequestWithPendingRequests)1882 TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
1883 const size_t kMaxSockets = 5;
1884 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
1885
1886 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1887
1888 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1889 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
1890
1891 // Queue up all the requests
1892 for (size_t i = 0; i < kNumberOfRequests; ++i)
1893 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1894 IsError(ERR_IO_PENDING));
1895
1896 for (size_t i = 0; i < kNumberOfRequests; ++i)
1897 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1898 }
1899
1900 // Make sure that pending requests that complete synchronously get serviced
1901 // after active requests fail. See https://crbug.com/723748
TEST_F(ClientSocketPoolBaseTest,HandleMultipleSyncFailuresAfterAsyncFailure)1902 TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1903 const size_t kNumberOfRequests = 10;
1904 const size_t kMaxSockets = 1;
1905 CreatePool(kMaxSockets, kMaxSockets);
1906
1907 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1908
1909 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1910 IsError(ERR_IO_PENDING));
1911
1912 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1913
1914 // Queue up all the other requests
1915 for (size_t i = 1; i < kNumberOfRequests; ++i)
1916 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1917 IsError(ERR_IO_PENDING));
1918
1919 // Make sure all requests fail, instead of hanging.
1920 for (size_t i = 0; i < kNumberOfRequests; ++i)
1921 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1922 }
1923
TEST_F(ClientSocketPoolBaseTest,CancelActiveRequestThenRequestSocket)1924 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
1925 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1926
1927 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1928
1929 ClientSocketHandle handle;
1930 TestCompletionCallback callback;
1931 int rv = handle.Init(
1932 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
1933 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1934 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
1935 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1936
1937 // Cancel the active request.
1938 handle.Reset();
1939
1940 rv = handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
1941 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1942 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1943 pool_.get(), NetLogWithSource());
1944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1945 EXPECT_THAT(callback.WaitForResult(), IsOk());
1946
1947 EXPECT_FALSE(handle.is_reused());
1948 TestLoadTimingInfoConnectedNotReused(handle);
1949 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1950 }
1951
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsForced)1952 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
1953 const char kReason[] = "Really nifty reason";
1954
1955 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1956 ClientSocketHandle handle;
1957 TestCompletionCallback callback;
1958 RecordingBoundTestNetLog log;
1959 int rv = handle.Init(
1960 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
1961 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1962 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
1963 EXPECT_THAT(rv, IsOk());
1964 ASSERT_TRUE(handle.socket());
1965 NetLogSource source = handle.socket()->NetLog().source();
1966 handle.Reset();
1967 EXPECT_EQ(1, pool_->IdleSocketCount());
1968 pool_->CloseIdleSockets(kReason);
1969 ExpectSocketClosedWithReason(source, kReason);
1970 }
1971
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsInGroupForced)1972 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
1973 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1974 TestCompletionCallback callback;
1975 RecordingBoundTestNetLog log;
1976 ClientSocketHandle handle1;
1977 int rv = handle1.Init(
1978 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
1979 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1980 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
1981 EXPECT_THAT(rv, IsOk());
1982 ClientSocketHandle handle2;
1983 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
1984 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1985 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1986 pool_.get(), log.bound());
1987 ClientSocketHandle handle3;
1988 rv = handle3.Init(TestGroupId("b"), params_, base::nullopt, LOWEST,
1989 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1990 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1991 pool_.get(), log.bound());
1992 EXPECT_THAT(rv, IsOk());
1993 handle1.Reset();
1994 handle2.Reset();
1995 handle3.Reset();
1996 EXPECT_EQ(3, pool_->IdleSocketCount());
1997 pool_->CloseIdleSocketsInGroup(TestGroupId("a"), "Very good reason");
1998 EXPECT_EQ(1, pool_->IdleSocketCount());
1999 }
2000
TEST_F(ClientSocketPoolBaseTest,CleanUpUnusableIdleSockets)2001 TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
2002 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2003 ClientSocketHandle handle;
2004 TestCompletionCallback callback;
2005 RecordingBoundTestNetLog log;
2006 int rv = handle.Init(
2007 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
2008 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2009 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
2010 EXPECT_THAT(rv, IsOk());
2011 StreamSocket* socket = handle.socket();
2012 ASSERT_TRUE(socket);
2013 handle.Reset();
2014 EXPECT_EQ(1, pool_->IdleSocketCount());
2015
2016 // Disconnect socket now to make the socket unusable.
2017 NetLogSource source = socket->NetLog().source();
2018 socket->Disconnect();
2019 ClientSocketHandle handle2;
2020 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2021 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2022 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2023 pool_.get(), log.bound());
2024 EXPECT_THAT(rv, IsOk());
2025 EXPECT_FALSE(handle2.is_reused());
2026
2027 // This is admittedly not an accurate error in this case, but normally code
2028 // doesn't secretly keep a raw pointers to sockets returned to the socket pool
2029 // and close them out of band, so discovering an idle socket was closed when
2030 // trying to reuse it normally means it was closed by the remote side.
2031 ExpectSocketClosedWithReason(
2032 source, TransportClientSocketPool::kRemoteSideClosedConnection);
2033 }
2034
2035 // Regression test for http://crbug.com/17985.
TEST_F(ClientSocketPoolBaseTest,GroupWithPendingRequestsIsNotEmpty)2036 TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
2037 const int kMaxSockets = 3;
2038 const int kMaxSocketsPerGroup = 2;
2039 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
2040
2041 const RequestPriority kHighPriority = HIGHEST;
2042
2043 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2044 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2045
2046 // This is going to be a pending request in an otherwise empty group.
2047 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2048 IsError(ERR_IO_PENDING));
2049
2050 // Reach the maximum socket limit.
2051 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2052
2053 // Create a stalled group with high priorities.
2054 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
2055 IsError(ERR_IO_PENDING));
2056 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
2057 IsError(ERR_IO_PENDING));
2058
2059 // Release the first two sockets from TestGroupId("a"). Because this is a
2060 // keepalive, the first release will unblock the pending request for
2061 // TestGroupId("a"). The second release will unblock a request for "c",
2062 // because it is the next high priority socket.
2063 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
2064 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
2065
2066 // Closing idle sockets should not get us into trouble, but in the bug
2067 // we were hitting a CHECK here.
2068 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2069 pool_->CloseIdleSockets("Very good reason");
2070
2071 // Run the released socket wakeups.
2072 base::RunLoop().RunUntilIdle();
2073 }
2074
TEST_F(ClientSocketPoolBaseTest,BasicAsynchronous)2075 TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
2076 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2077
2078 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2079 ClientSocketHandle handle;
2080 TestCompletionCallback callback;
2081 RecordingBoundTestNetLog log;
2082 int rv = handle.Init(
2083 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
2084 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2085 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
2086 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2087 EXPECT_EQ(LOAD_STATE_CONNECTING,
2088 pool_->GetLoadState(TestGroupId("a"), &handle));
2089 TestLoadTimingInfoNotConnected(handle);
2090
2091 EXPECT_THAT(callback.WaitForResult(), IsOk());
2092 EXPECT_TRUE(handle.is_initialized());
2093 EXPECT_TRUE(handle.socket());
2094 TestLoadTimingInfoConnectedNotReused(handle);
2095
2096 handle.Reset();
2097 TestLoadTimingInfoNotConnected(handle);
2098
2099 auto entries = log.GetEntries();
2100
2101 EXPECT_EQ(5u, entries.size());
2102 EXPECT_TRUE(LogContainsEvent(
2103 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2104 NetLogEventPhase::NONE));
2105 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2106 EXPECT_TRUE(LogContainsEvent(
2107 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2108 NetLogEventPhase::NONE));
2109 EXPECT_TRUE(LogContainsEvent(entries, 3,
2110 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
2111 NetLogEventPhase::NONE));
2112 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
2113 }
2114
TEST_F(ClientSocketPoolBaseTest,InitConnectionAsynchronousFailure)2115 TEST_F(ClientSocketPoolBaseTest,
2116 InitConnectionAsynchronousFailure) {
2117 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2118
2119 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2120 ClientSocketHandle handle;
2121 TestCompletionCallback callback;
2122 RecordingBoundTestNetLog log;
2123 // Set the additional error state members to ensure that they get cleared.
2124 handle.set_is_ssl_error(true);
2125 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
2126 EXPECT_EQ(
2127 ERR_IO_PENDING,
2128 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2129 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2130 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2131 pool_.get(), log.bound()));
2132 EXPECT_EQ(LOAD_STATE_CONNECTING,
2133 pool_->GetLoadState(TestGroupId("a"), &handle));
2134 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2135 EXPECT_FALSE(handle.is_ssl_error());
2136 EXPECT_FALSE(handle.ssl_cert_request_info());
2137
2138 auto entries = log.GetEntries();
2139
2140 EXPECT_EQ(4u, entries.size());
2141 EXPECT_TRUE(LogContainsEvent(
2142 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2143 NetLogEventPhase::NONE));
2144 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2145 EXPECT_TRUE(LogContainsEvent(
2146 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2147 NetLogEventPhase::NONE));
2148 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
2149 }
2150
2151 // Check that an async ConnectJob failure does not result in creation of a new
2152 // ConnectJob when there's another pending request also waiting on its own
2153 // ConnectJob. See http://crbug.com/463960.
TEST_F(ClientSocketPoolBaseTest,AsyncFailureWithPendingRequestWithJob)2154 TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
2155 CreatePool(2, 2);
2156 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2157
2158 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2159 IsError(ERR_IO_PENDING));
2160 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2161 IsError(ERR_IO_PENDING));
2162
2163 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2164 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2165
2166 EXPECT_EQ(2, client_socket_factory_.allocation_count());
2167 }
2168
TEST_F(ClientSocketPoolBaseTest,TwoRequestsCancelOne)2169 TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
2170 // TODO(eroman): Add back the log expectations! Removed them because the
2171 // ordering is difficult, and some may fire during destructor.
2172 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2173
2174 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2175 ClientSocketHandle handle;
2176 TestCompletionCallback callback;
2177 ClientSocketHandle handle2;
2178 TestCompletionCallback callback2;
2179
2180 EXPECT_EQ(
2181 ERR_IO_PENDING,
2182 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2183 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2184 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2185 pool_.get(), NetLogWithSource()));
2186 RecordingBoundTestNetLog log2;
2187 EXPECT_EQ(
2188 ERR_IO_PENDING,
2189 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2190 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2191 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2192 pool_.get(), NetLogWithSource()));
2193
2194 handle.Reset();
2195
2196
2197 // At this point, request 2 is just waiting for the connect job to finish.
2198
2199 EXPECT_THAT(callback2.WaitForResult(), IsOk());
2200 handle2.Reset();
2201
2202 // Now request 2 has actually finished.
2203 // TODO(eroman): Add back log expectations.
2204 }
2205
TEST_F(ClientSocketPoolBaseTest,CancelRequestLimitsJobs)2206 TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
2207 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2208
2209 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2210
2211 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
2212 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
2213 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
2214 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
2215
2216 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2217 static_cast<int>(
2218 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
2219 (*requests())[2]->handle()->Reset();
2220 (*requests())[3]->handle()->Reset();
2221 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2222 static_cast<int>(
2223 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
2224
2225 (*requests())[1]->handle()->Reset();
2226 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2227 static_cast<int>(
2228 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
2229
2230 (*requests())[0]->handle()->Reset();
2231 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2232 static_cast<int>(
2233 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
2234 }
2235
2236 // When requests and ConnectJobs are not coupled, the request will get serviced
2237 // by whatever comes first.
TEST_F(ClientSocketPoolBaseTest,ReleaseSockets)2238 TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
2239 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2240
2241 // Start job 1 (async OK)
2242 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2243
2244 std::vector<TestSocketRequest*> request_order;
2245 size_t completion_count; // unused
2246 TestSocketRequest req1(&request_order, &completion_count);
2247 int rv = req1.handle()->Init(
2248 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
2249 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2250 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2251 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2252 EXPECT_THAT(req1.WaitForResult(), IsOk());
2253
2254 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
2255 // without a job.
2256 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2257
2258 TestSocketRequest req2(&request_order, &completion_count);
2259 rv = req2.handle()->Init(
2260 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
2261 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2262 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2263 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2264 TestSocketRequest req3(&request_order, &completion_count);
2265 rv = req3.handle()->Init(
2266 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
2267 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2268 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2269 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2270
2271 // Both Requests 2 and 3 are pending. We release socket 1 which should
2272 // service request 2. Request 3 should still be waiting.
2273 req1.handle()->Reset();
2274 // Run the released socket wakeups.
2275 base::RunLoop().RunUntilIdle();
2276 ASSERT_TRUE(req2.handle()->socket());
2277 EXPECT_THAT(req2.WaitForResult(), IsOk());
2278 EXPECT_FALSE(req3.handle()->socket());
2279
2280 // Signal job 2, which should service request 3.
2281
2282 client_socket_factory_.SignalJobs();
2283 EXPECT_THAT(req3.WaitForResult(), IsOk());
2284
2285 ASSERT_EQ(3u, request_order.size());
2286 EXPECT_EQ(&req1, request_order[0]);
2287 EXPECT_EQ(&req2, request_order[1]);
2288 EXPECT_EQ(&req3, request_order[2]);
2289 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2290 }
2291
2292 // The requests are not coupled to the jobs. So, the requests should finish in
2293 // their priority / insertion order.
TEST_F(ClientSocketPoolBaseTest,PendingJobCompletionOrder)2294 TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
2295 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2296 // First two jobs are async.
2297 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2298
2299 std::vector<TestSocketRequest*> request_order;
2300 size_t completion_count; // unused
2301 TestSocketRequest req1(&request_order, &completion_count);
2302 int rv = req1.handle()->Init(
2303 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
2304 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2305 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2306 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2307
2308 TestSocketRequest req2(&request_order, &completion_count);
2309 rv = req2.handle()->Init(
2310 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
2311 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2312 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2313 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2314
2315 // The pending job is sync.
2316 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2317
2318 TestSocketRequest req3(&request_order, &completion_count);
2319 rv = req3.handle()->Init(
2320 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
2321 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2322 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2323 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2324
2325 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2326 EXPECT_THAT(req2.WaitForResult(), IsOk());
2327 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2328
2329 ASSERT_EQ(3u, request_order.size());
2330 EXPECT_EQ(&req1, request_order[0]);
2331 EXPECT_EQ(&req2, request_order[1]);
2332 EXPECT_EQ(&req3, request_order[2]);
2333 }
2334
2335 // Test GetLoadState in the case there's only one socket request.
TEST_F(ClientSocketPoolBaseTest,LoadStateOneRequest)2336 TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
2337 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2338 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2339
2340 ClientSocketHandle handle;
2341 TestCompletionCallback callback;
2342 int rv = handle.Init(
2343 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
2344 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2345 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2346 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2347 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2348
2349 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2350 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2351
2352 // No point in completing the connection, since ClientSocketHandles only
2353 // expect the LoadState to be checked while connecting.
2354 }
2355
2356 // Test GetLoadState in the case there are two socket requests.
TEST_F(ClientSocketPoolBaseTest,LoadStateTwoRequests)2357 TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2358 CreatePool(2, 2);
2359 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2360
2361 ClientSocketHandle handle;
2362 TestCompletionCallback callback;
2363 int rv = handle.Init(
2364 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
2365 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2366 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2367 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2368 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2369
2370 ClientSocketHandle handle2;
2371 TestCompletionCallback callback2;
2372 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2373 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2374 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2375 pool_.get(), NetLogWithSource());
2376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2377 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2378
2379 // Each handle should reflect the state of its own job.
2380 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2381 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2382
2383 // Update the state of the first job.
2384 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2385
2386 // Only the state of the first request should have changed.
2387 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2388 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2389
2390 // Update the state of the second job.
2391 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_SSL_HANDSHAKE);
2392
2393 // Only the state of the second request should have changed.
2394 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2395 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2396
2397 // Second job connects and the first request gets the socket. The
2398 // second handle switches to the state of the remaining ConnectJob.
2399 client_socket_factory_.SignalJob(1);
2400 EXPECT_THAT(callback.WaitForResult(), IsOk());
2401 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2402 }
2403
2404 // Test GetLoadState in the case the per-group limit is reached.
TEST_F(ClientSocketPoolBaseTest,LoadStateGroupLimit)2405 TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2406 CreatePool(2, 1);
2407 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2408
2409 ClientSocketHandle handle;
2410 TestCompletionCallback callback;
2411 int rv = handle.Init(
2412 TestGroupId("a"), params_, base::nullopt, MEDIUM, SocketTag(),
2413 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2414 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2415 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2416 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2417
2418 // Request another socket from the same pool, buth with a higher priority.
2419 // The first request should now be stalled at the socket group limit.
2420 ClientSocketHandle handle2;
2421 TestCompletionCallback callback2;
2422 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
2423 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2424 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2425 pool_.get(), NetLogWithSource());
2426 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2427 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2428 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2429
2430 // The first handle should remain stalled as the other socket goes through
2431 // the connect process.
2432
2433 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2434 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2435 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2436
2437 client_socket_factory_.SignalJob(0);
2438 EXPECT_THAT(callback2.WaitForResult(), IsOk());
2439 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2440
2441 // Closing the second socket should cause the stalled handle to finally get a
2442 // ConnectJob.
2443 handle2.socket()->Disconnect();
2444 handle2.Reset();
2445 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2446 }
2447
2448 // Test GetLoadState in the case the per-pool limit is reached.
TEST_F(ClientSocketPoolBaseTest,LoadStatePoolLimit)2449 TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2450 CreatePool(2, 2);
2451 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2452
2453 ClientSocketHandle handle;
2454 TestCompletionCallback callback;
2455 int rv = handle.Init(
2456 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(),
2457 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2458 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2459 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2460
2461 // Request for socket from another pool.
2462 ClientSocketHandle handle2;
2463 TestCompletionCallback callback2;
2464 rv = handle2.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
2465 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2466 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2467 pool_.get(), NetLogWithSource());
2468 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2469
2470 // Request another socket from the first pool. Request should stall at the
2471 // socket pool limit.
2472 ClientSocketHandle handle3;
2473 TestCompletionCallback callback3;
2474 rv = handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2475 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2476 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2477 pool_.get(), NetLogWithSource());
2478 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2479
2480 // The third handle should remain stalled as the other sockets in its group
2481 // goes through the connect process.
2482
2483 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2484 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2485
2486 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2487 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2488 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2489
2490 client_socket_factory_.SignalJob(0);
2491 EXPECT_THAT(callback.WaitForResult(), IsOk());
2492 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2493
2494 // Closing a socket should allow the stalled handle to finally get a new
2495 // ConnectJob.
2496 handle.socket()->Disconnect();
2497 handle.Reset();
2498 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
2499 }
2500
TEST_F(ClientSocketPoolBaseTest,CertError)2501 TEST_F(ClientSocketPoolBaseTest, CertError) {
2502 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2503 connect_job_factory_->set_job_type(TestConnectJob::kMockCertErrorJob);
2504
2505 ClientSocketHandle handle;
2506 TestCompletionCallback callback;
2507 EXPECT_EQ(
2508 ERR_CERT_COMMON_NAME_INVALID,
2509 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2510 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2511 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2512 pool_.get(), NetLogWithSource()));
2513 EXPECT_TRUE(handle.is_initialized());
2514 EXPECT_TRUE(handle.socket());
2515 }
2516
TEST_F(ClientSocketPoolBaseTest,AsyncCertError)2517 TEST_F(ClientSocketPoolBaseTest, AsyncCertError) {
2518 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2519
2520 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingCertErrorJob);
2521 ClientSocketHandle handle;
2522 TestCompletionCallback callback;
2523 EXPECT_EQ(
2524 ERR_IO_PENDING,
2525 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2526 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2527 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2528 pool_.get(), NetLogWithSource()));
2529 EXPECT_EQ(LOAD_STATE_CONNECTING,
2530 pool_->GetLoadState(TestGroupId("a"), &handle));
2531 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CERT_COMMON_NAME_INVALID));
2532 EXPECT_TRUE(handle.is_initialized());
2533 EXPECT_TRUE(handle.socket());
2534 }
2535
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorStateSynchronous)2536 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2537 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2538 connect_job_factory_->set_job_type(
2539 TestConnectJob::kMockAdditionalErrorStateJob);
2540
2541 ClientSocketHandle handle;
2542 TestCompletionCallback callback;
2543 EXPECT_EQ(
2544 ERR_CONNECTION_FAILED,
2545 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2546 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2547 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2548 pool_.get(), NetLogWithSource()));
2549 EXPECT_FALSE(handle.is_initialized());
2550 EXPECT_FALSE(handle.socket());
2551 EXPECT_TRUE(handle.is_ssl_error());
2552 EXPECT_TRUE(handle.ssl_cert_request_info());
2553 }
2554
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorStateAsynchronous)2555 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2556 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2557
2558 connect_job_factory_->set_job_type(
2559 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2560 ClientSocketHandle handle;
2561 TestCompletionCallback callback;
2562 EXPECT_EQ(
2563 ERR_IO_PENDING,
2564 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2565 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2566 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2567 pool_.get(), NetLogWithSource()));
2568 EXPECT_EQ(LOAD_STATE_CONNECTING,
2569 pool_->GetLoadState(TestGroupId("a"), &handle));
2570 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2571 EXPECT_FALSE(handle.is_initialized());
2572 EXPECT_FALSE(handle.socket());
2573 EXPECT_TRUE(handle.is_ssl_error());
2574 EXPECT_TRUE(handle.ssl_cert_request_info());
2575 }
2576
2577 // Make sure we can reuse sockets.
TEST_F(ClientSocketPoolBaseTest,CleanupTimedOutIdleSocketsReuse)2578 TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
2579 CreatePoolWithIdleTimeouts(
2580 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2581 base::TimeDelta(), // Time out unused sockets immediately.
2582 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2583
2584 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2585
2586 ClientSocketHandle handle;
2587 TestCompletionCallback callback;
2588 int rv = handle.Init(
2589 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
2590 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2591 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2592 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2593 EXPECT_EQ(LOAD_STATE_CONNECTING,
2594 pool_->GetLoadState(TestGroupId("a"), &handle));
2595 ASSERT_THAT(callback.WaitForResult(), IsOk());
2596
2597 // Use and release the socket.
2598 EXPECT_EQ(1, handle.socket()->Write(nullptr, 1, CompletionOnceCallback(),
2599 TRAFFIC_ANNOTATION_FOR_TESTS));
2600 TestLoadTimingInfoConnectedNotReused(handle);
2601 handle.Reset();
2602
2603 // Should now have one idle socket.
2604 ASSERT_EQ(1, pool_->IdleSocketCount());
2605
2606 // Request a new socket. This should reuse the old socket and complete
2607 // synchronously.
2608 RecordingBoundTestNetLog log;
2609 rv = handle.Init(
2610 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
2611 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2612 ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound());
2613 ASSERT_THAT(rv, IsOk());
2614 EXPECT_TRUE(handle.is_reused());
2615 TestLoadTimingInfoConnectedReused(handle);
2616
2617 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
2618 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2619 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
2620
2621 auto entries = log.GetEntries();
2622 EXPECT_TRUE(LogContainsEvent(
2623 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2624 NetLogEventPhase::NONE));
2625 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2626 EXPECT_TRUE(LogContainsEntryWithType(
2627 entries, 2, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2628 }
2629
2630 // Make sure we cleanup old unused sockets.
TEST_F(ClientSocketPoolBaseTest,CleanupTimedOutIdleSocketsNoReuse)2631 TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
2632 CreatePoolWithIdleTimeouts(
2633 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2634 base::TimeDelta(), // Time out unused sockets immediately
2635 base::TimeDelta()); // Time out used sockets immediately
2636
2637 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2638
2639 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2640
2641 ClientSocketHandle handle;
2642 TestCompletionCallback callback;
2643 int rv = handle.Init(
2644 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
2645 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2646 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2647 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2648 EXPECT_EQ(LOAD_STATE_CONNECTING,
2649 pool_->GetLoadState(TestGroupId("a"), &handle));
2650
2651 ClientSocketHandle handle2;
2652 TestCompletionCallback callback2;
2653 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2654 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2655 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2656 pool_.get(), NetLogWithSource());
2657 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2658 EXPECT_EQ(LOAD_STATE_CONNECTING,
2659 pool_->GetLoadState(TestGroupId("a"), &handle2));
2660
2661 // Cancel one of the requests. Wait for the other, which will get the first
2662 // job. Release the socket. Run the loop again to make sure the second
2663 // socket is sitting idle and the first one is released (since ReleaseSocket()
2664 // just posts a DoReleaseSocket() task).
2665
2666 handle.Reset();
2667 ASSERT_THAT(callback2.WaitForResult(), IsOk());
2668 // Get the NetLogSource for the socket, so the time out reason can be checked
2669 // at the end of the test.
2670 NetLogSource net_log_source2 = handle2.socket()->NetLog().source();
2671 // Use the socket.
2672 EXPECT_EQ(1, handle2.socket()->Write(nullptr, 1, CompletionOnceCallback(),
2673 TRAFFIC_ANNOTATION_FOR_TESTS));
2674 handle2.Reset();
2675
2676 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2677 // actually become pending until 2ms after they have been created. In order
2678 // to flush all tasks, we need to wait so that we know there are no
2679 // soon-to-be-pending tasks waiting.
2680 FastForwardBy(base::TimeDelta::FromMilliseconds(10));
2681
2682 // Both sockets should now be idle.
2683 ASSERT_EQ(2, pool_->IdleSocketCount());
2684
2685 // Request a new socket. This should cleanup the unused and timed out ones.
2686 // A new socket will be created rather than reusing the idle one.
2687 RecordingBoundTestNetLog log;
2688 TestCompletionCallback callback3;
2689 rv = handle.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2690 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2691 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2692 pool_.get(), log.bound());
2693 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2694 ASSERT_THAT(callback3.WaitForResult(), IsOk());
2695 EXPECT_FALSE(handle.is_reused());
2696
2697 // Make sure the idle socket is closed.
2698 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
2699 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2700 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
2701
2702 auto entries = log.GetEntries();
2703 EXPECT_FALSE(LogContainsEntryWithType(
2704 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2705 ExpectSocketClosedWithReason(
2706 net_log_source2, TransportClientSocketPool::kIdleTimeLimitExpired);
2707 }
2708
2709 // Make sure that we process all pending requests even when we're stalling
2710 // because of multiple releasing disconnected sockets.
TEST_F(ClientSocketPoolBaseTest,MultipleReleasingDisconnectedSockets)2711 TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2712 CreatePoolWithIdleTimeouts(
2713 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2714 base::TimeDelta(), // Time out unused sockets immediately.
2715 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2716
2717 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2718
2719 // Startup 4 connect jobs. Two of them will be pending.
2720
2721 ClientSocketHandle handle;
2722 TestCompletionCallback callback;
2723 int rv = handle.Init(
2724 TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(),
2725 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2726 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2727 EXPECT_THAT(rv, IsOk());
2728
2729 ClientSocketHandle handle2;
2730 TestCompletionCallback callback2;
2731 rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2732 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2733 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2734 pool_.get(), NetLogWithSource());
2735 EXPECT_THAT(rv, IsOk());
2736
2737 ClientSocketHandle handle3;
2738 TestCompletionCallback callback3;
2739 rv = handle3.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2740 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2741 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2742 pool_.get(), NetLogWithSource());
2743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2744
2745 ClientSocketHandle handle4;
2746 TestCompletionCallback callback4;
2747 rv = handle4.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2748 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2749 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
2750 pool_.get(), NetLogWithSource());
2751 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2752
2753 // Release two disconnected sockets.
2754
2755 handle.socket()->Disconnect();
2756 handle.Reset();
2757 handle2.socket()->Disconnect();
2758 handle2.Reset();
2759
2760 EXPECT_THAT(callback3.WaitForResult(), IsOk());
2761 EXPECT_FALSE(handle3.is_reused());
2762 EXPECT_THAT(callback4.WaitForResult(), IsOk());
2763 EXPECT_FALSE(handle4.is_reused());
2764 }
2765
2766 // Regression test for http://crbug.com/42267.
2767 // When DoReleaseSocket() is processed for one socket, it is blocked because the
2768 // other stalled groups all have releasing sockets, so no progress can be made.
TEST_F(ClientSocketPoolBaseTest,SocketLimitReleasingSockets)2769 TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2770 CreatePoolWithIdleTimeouts(
2771 4 /* socket limit */, 4 /* socket limit per group */,
2772 base::TimeDelta(), // Time out unused sockets immediately.
2773 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2774
2775 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2776
2777 // Max out the socket limit with 2 per group.
2778
2779 ClientSocketHandle handle_a[4];
2780 TestCompletionCallback callback_a[4];
2781 ClientSocketHandle handle_b[4];
2782 TestCompletionCallback callback_b[4];
2783
2784 for (int i = 0; i < 2; ++i) {
2785 EXPECT_EQ(OK, handle_a[i].Init(TestGroupId("a"), params_, base::nullopt,
2786 LOWEST, SocketTag(),
2787 ClientSocketPool::RespectLimits::ENABLED,
2788 callback_a[i].callback(),
2789 ClientSocketPool::ProxyAuthCallback(),
2790 pool_.get(), NetLogWithSource()));
2791 EXPECT_EQ(OK, handle_b[i].Init(TestGroupId("b"), params_, base::nullopt,
2792 LOWEST, SocketTag(),
2793 ClientSocketPool::RespectLimits::ENABLED,
2794 callback_b[i].callback(),
2795 ClientSocketPool::ProxyAuthCallback(),
2796 pool_.get(), NetLogWithSource()));
2797 }
2798
2799 // Make 4 pending requests, 2 per group.
2800
2801 for (int i = 2; i < 4; ++i) {
2802 EXPECT_EQ(
2803 ERR_IO_PENDING,
2804 handle_a[i].Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
2805 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2806 callback_a[i].callback(),
2807 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2808 NetLogWithSource()));
2809 EXPECT_EQ(
2810 ERR_IO_PENDING,
2811 handle_b[i].Init(TestGroupId("b"), params_, base::nullopt, LOWEST,
2812 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2813 callback_b[i].callback(),
2814 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2815 NetLogWithSource()));
2816 }
2817
2818 // Release b's socket first. The order is important, because in
2819 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2820 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2821 // first, which has a releasing socket, so it refuses to start up another
2822 // ConnectJob. So, we used to infinite loop on this.
2823 handle_b[0].socket()->Disconnect();
2824 handle_b[0].Reset();
2825 handle_a[0].socket()->Disconnect();
2826 handle_a[0].Reset();
2827
2828 // Used to get stuck here.
2829 base::RunLoop().RunUntilIdle();
2830
2831 handle_b[1].socket()->Disconnect();
2832 handle_b[1].Reset();
2833 handle_a[1].socket()->Disconnect();
2834 handle_a[1].Reset();
2835
2836 for (int i = 2; i < 4; ++i) {
2837 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2838 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
2839 }
2840 }
2841
TEST_F(ClientSocketPoolBaseTest,ReleasingDisconnectedSocketsMaintainsPriorityOrder)2842 TEST_F(ClientSocketPoolBaseTest,
2843 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2844 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2845
2846 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2847
2848 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2849 IsError(ERR_IO_PENDING));
2850 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2851 IsError(ERR_IO_PENDING));
2852 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2853 IsError(ERR_IO_PENDING));
2854 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2855 IsError(ERR_IO_PENDING));
2856
2857 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2858 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
2859 EXPECT_EQ(2u, completion_count());
2860
2861 // Releases one connection.
2862 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2863 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
2864
2865 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2866 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
2867 EXPECT_EQ(4u, completion_count());
2868
2869 EXPECT_EQ(1, GetOrderOfRequest(1));
2870 EXPECT_EQ(2, GetOrderOfRequest(2));
2871 EXPECT_EQ(3, GetOrderOfRequest(3));
2872 EXPECT_EQ(4, GetOrderOfRequest(4));
2873
2874 // Make sure we test order of all requests made.
2875 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
2876 }
2877
2878 class TestReleasingSocketRequest : public TestCompletionCallbackBase {
2879 public:
TestReleasingSocketRequest(TransportClientSocketPool * pool,int expected_result,bool reset_releasing_handle)2880 TestReleasingSocketRequest(TransportClientSocketPool* pool,
2881 int expected_result,
2882 bool reset_releasing_handle)
2883 : pool_(pool),
2884 expected_result_(expected_result),
2885 reset_releasing_handle_(reset_releasing_handle) {}
2886
2887 ~TestReleasingSocketRequest() override = default;
2888
handle()2889 ClientSocketHandle* handle() { return &handle_; }
2890
callback()2891 CompletionOnceCallback callback() {
2892 return base::BindOnce(&TestReleasingSocketRequest::OnComplete,
2893 base::Unretained(this));
2894 }
2895
2896 private:
OnComplete(int result)2897 void OnComplete(int result) {
2898 SetResult(result);
2899 if (reset_releasing_handle_)
2900 handle_.Reset();
2901
2902 EXPECT_EQ(
2903 expected_result_,
2904 handle2_.Init(
2905 TestGroupId("a"),
2906 ClientSocketPool::SocketParams::CreateForHttpForTesting(),
2907 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
2908 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2909 ClientSocketPool::ProxyAuthCallback(), pool_, NetLogWithSource()));
2910 }
2911
2912 TransportClientSocketPool* const pool_;
2913 int expected_result_;
2914 bool reset_releasing_handle_;
2915 ClientSocketHandle handle_;
2916 ClientSocketHandle handle2_;
2917 };
2918
2919
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorSocketsDontUseSlot)2920 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2921 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2922
2923 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2924 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2925 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2926
2927 EXPECT_EQ(static_cast<int>(requests_size()),
2928 client_socket_factory_.allocation_count());
2929
2930 connect_job_factory_->set_job_type(
2931 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2932 TestReleasingSocketRequest req(pool_.get(), OK, false);
2933 EXPECT_EQ(ERR_IO_PENDING,
2934 req.handle()->Init(
2935 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2936 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2937 req.callback(), ClientSocketPool::ProxyAuthCallback(),
2938 pool_.get(), NetLogWithSource()));
2939 // The next job should complete synchronously
2940 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2941
2942 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2943 EXPECT_FALSE(req.handle()->is_initialized());
2944 EXPECT_FALSE(req.handle()->socket());
2945 EXPECT_TRUE(req.handle()->is_ssl_error());
2946 EXPECT_TRUE(req.handle()->ssl_cert_request_info());
2947 }
2948
2949 // http://crbug.com/44724 regression test.
2950 // We start releasing the pool when we flush on network change. When that
2951 // happens, the only active references are in the ClientSocketHandles. When a
2952 // ConnectJob completes and calls back into the last ClientSocketHandle, that
2953 // callback can release the last reference and delete the pool. After the
2954 // callback finishes, we go back to the stack frame within the now-deleted pool.
2955 // Executing any code that refers to members of the now-deleted pool can cause
2956 // crashes.
TEST_F(ClientSocketPoolBaseTest,CallbackThatReleasesPool)2957 TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2958 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2959 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2960
2961 ClientSocketHandle handle;
2962 TestCompletionCallback callback;
2963 EXPECT_EQ(
2964 ERR_IO_PENDING,
2965 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2966 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2967 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2968 pool_.get(), NetLogWithSource()));
2969
2970 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
2971
2972 // We'll call back into this now.
2973 callback.WaitForResult();
2974 }
2975
TEST_F(ClientSocketPoolBaseTest,DoNotReuseSocketAfterFlush)2976 TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2977 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2978 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2979
2980 ClientSocketHandle handle;
2981 TestCompletionCallback callback;
2982 EXPECT_EQ(
2983 ERR_IO_PENDING,
2984 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
2985 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2986 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2987 pool_.get(), NetLogWithSource()));
2988 EXPECT_THAT(callback.WaitForResult(), IsOk());
2989 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2990 NetLogSource source = handle.socket()->NetLog().source();
2991
2992 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
2993
2994 handle.Reset();
2995 base::RunLoop().RunUntilIdle();
2996
2997 EXPECT_EQ(
2998 ERR_IO_PENDING,
2999 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3000 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3001 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3002 pool_.get(), NetLogWithSource()));
3003 EXPECT_THAT(callback.WaitForResult(), IsOk());
3004 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
3005
3006 ExpectSocketClosedWithReason(
3007 source, TransportClientSocketPool::kSocketGenerationOutOfDate);
3008 }
3009
3010 class ConnectWithinCallback : public TestCompletionCallbackBase {
3011 public:
ConnectWithinCallback(const ClientSocketPool::GroupId & group_id,const scoped_refptr<ClientSocketPool::SocketParams> & params,TransportClientSocketPool * pool)3012 ConnectWithinCallback(
3013 const ClientSocketPool::GroupId& group_id,
3014 const scoped_refptr<ClientSocketPool::SocketParams>& params,
3015 TransportClientSocketPool* pool)
3016 : group_id_(group_id), params_(params), pool_(pool) {}
3017
3018 ~ConnectWithinCallback() override = default;
3019
WaitForNestedResult()3020 int WaitForNestedResult() {
3021 return nested_callback_.WaitForResult();
3022 }
3023
callback()3024 CompletionOnceCallback callback() {
3025 return base::BindOnce(&ConnectWithinCallback::OnComplete,
3026 base::Unretained(this));
3027 }
3028
3029 private:
OnComplete(int result)3030 void OnComplete(int result) {
3031 SetResult(result);
3032 EXPECT_EQ(
3033 ERR_IO_PENDING,
3034 handle_.Init(group_id_, params_, base::nullopt, DEFAULT_PRIORITY,
3035 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3036 nested_callback_.callback(),
3037 ClientSocketPool::ProxyAuthCallback(), pool_,
3038 NetLogWithSource()));
3039 }
3040
3041 const ClientSocketPool::GroupId group_id_;
3042 const scoped_refptr<ClientSocketPool::SocketParams> params_;
3043 TransportClientSocketPool* const pool_;
3044 ClientSocketHandle handle_;
3045 TestCompletionCallback nested_callback_;
3046
3047 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
3048 };
3049
TEST_F(ClientSocketPoolBaseTest,AbortAllRequestsOnFlush)3050 TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
3051 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3052
3053 // First job will be waiting until it gets aborted.
3054 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3055
3056 ClientSocketHandle handle;
3057 ConnectWithinCallback callback(TestGroupId("a"), params_, pool_.get());
3058 EXPECT_EQ(
3059 ERR_IO_PENDING,
3060 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3061 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3062 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3063 pool_.get(), NetLogWithSource()));
3064
3065 // Second job will be started during the first callback, and will
3066 // asynchronously complete with OK.
3067 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3068 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
3069 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
3070 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
3071 }
3072
TEST_F(ClientSocketPoolBaseTest,BackupSocketWaitsForHostResolution)3073 TEST_F(ClientSocketPoolBaseTest, BackupSocketWaitsForHostResolution) {
3074 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3075 true /* enable_backup_connect_jobs */);
3076
3077 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3078 ClientSocketHandle handle;
3079 TestCompletionCallback callback;
3080 EXPECT_EQ(
3081 ERR_IO_PENDING,
3082 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3083 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3084 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3085 pool_.get(), NetLogWithSource()));
3086 // The backup timer fires but doesn't start a new ConnectJob while resolving
3087 // the hostname.
3088 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3089 FastForwardBy(base::TimeDelta::FromMilliseconds(
3090 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3091 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3092
3093 // Once the ConnectJob has finished resolving the hostname, the backup timer
3094 // will create a ConnectJob when it fires.
3095 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
3096 FastForwardBy(base::TimeDelta::FromMilliseconds(
3097 ClientSocketPool::kMaxConnectRetryIntervalMs));
3098 EXPECT_EQ(2, client_socket_factory_.allocation_count());
3099 }
3100
3101 // Test that no backup socket is created when a ConnectJob connects before it
3102 // completes.
TEST_F(ClientSocketPoolBaseTest,NoBackupSocketWhenConnected)3103 TEST_F(ClientSocketPoolBaseTest, NoBackupSocketWhenConnected) {
3104 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3105 true /* enable_backup_connect_jobs */);
3106
3107 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3108 ClientSocketHandle handle;
3109 TestCompletionCallback callback;
3110 EXPECT_EQ(
3111 ERR_IO_PENDING,
3112 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3113 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3114 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3115 pool_.get(), NetLogWithSource()));
3116 // The backup timer fires but doesn't start a new ConnectJob while resolving
3117 // the hostname.
3118 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3119 FastForwardBy(base::TimeDelta::FromMilliseconds(
3120 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3121 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3122
3123 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
3124 client_socket_factory_.SetJobHasEstablishedConnection(0);
3125 FastForwardBy(base::TimeDelta::FromMilliseconds(
3126 ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3127 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3128 }
3129
3130 // Cancel a pending socket request while we're at max sockets,
3131 // and verify that the backup socket firing doesn't cause a crash.
TEST_F(ClientSocketPoolBaseTest,BackupSocketCancelAtMaxSockets)3132 TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
3133 // Max 4 sockets globally, max 4 sockets per group.
3134 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3135 true /* enable_backup_connect_jobs */);
3136
3137 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3138 // timer.
3139 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3140 ClientSocketHandle handle;
3141 TestCompletionCallback callback;
3142 EXPECT_EQ(
3143 ERR_IO_PENDING,
3144 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3145 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3146 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3147 pool_.get(), NetLogWithSource()));
3148
3149 // Start (MaxSockets - 1) connected sockets to reach max sockets.
3150 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3151 ClientSocketHandle handles[kDefaultMaxSockets];
3152 for (int i = 1; i < kDefaultMaxSockets; ++i) {
3153 TestCompletionCallback callback;
3154 EXPECT_EQ(OK, handles[i].Init(TestGroupId("bar"), params_, base::nullopt,
3155 DEFAULT_PRIORITY, SocketTag(),
3156 ClientSocketPool::RespectLimits::ENABLED,
3157 callback.callback(),
3158 ClientSocketPool::ProxyAuthCallback(),
3159 pool_.get(), NetLogWithSource()));
3160 }
3161
3162 base::RunLoop().RunUntilIdle();
3163
3164 // Cancel the pending request.
3165 handle.Reset();
3166
3167 // Wait for the backup timer to fire (add some slop to ensure it fires)
3168 FastForwardBy(base::TimeDelta::FromMilliseconds(
3169 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
3170
3171 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
3172 }
3173
TEST_F(ClientSocketPoolBaseTest,CancelBackupSocketAfterCancelingAllRequests)3174 TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
3175 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3176 true /* enable_backup_connect_jobs */);
3177
3178 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3179 // timer.
3180 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3181 ClientSocketHandle handle;
3182 TestCompletionCallback callback;
3183 EXPECT_EQ(
3184 ERR_IO_PENDING,
3185 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3186 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3187 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3188 pool_.get(), NetLogWithSource()));
3189 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3190 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3191 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3192 TestGroupId("bar")));
3193 EXPECT_EQ(
3194 0u, pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("bar")));
3195
3196 // Cancel the socket request. This should cancel the backup timer. Wait for
3197 // the backup time to see if it indeed got canceled.
3198 handle.Reset();
3199 // Wait for the backup timer to fire (add some slop to ensure it fires)
3200 FastForwardBy(base::TimeDelta::FromMilliseconds(
3201 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
3202 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3203 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3204 }
3205
TEST_F(ClientSocketPoolBaseTest,CancelBackupSocketAfterFinishingAllRequests)3206 TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
3207 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3208 true /* enable_backup_connect_jobs */);
3209
3210 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3211 // timer.
3212 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3213 ClientSocketHandle handle;
3214 TestCompletionCallback callback;
3215 EXPECT_EQ(
3216 ERR_IO_PENDING,
3217 handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3218 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3219 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3220 pool_.get(), NetLogWithSource()));
3221 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3222 ClientSocketHandle handle2;
3223 TestCompletionCallback callback2;
3224 EXPECT_EQ(
3225 ERR_IO_PENDING,
3226 handle2.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY,
3227 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3228 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3229 pool_.get(), NetLogWithSource()));
3230 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3231 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3232
3233 // Cancel request 1 and then complete request 2. With the requests finished,
3234 // the backup timer should be cancelled.
3235 handle.Reset();
3236 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3237 // Wait for the backup timer to fire (add some slop to ensure it fires)
3238 FastForwardBy(base::TimeDelta::FromMilliseconds(
3239 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
3240 }
3241
3242 // Test delayed socket binding for the case where we have two connects,
3243 // and while one is waiting on a connect, the other frees up.
3244 // The socket waiting on a connect should switch immediately to the freed
3245 // up socket.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingWaitingForConnect)3246 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
3247 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3248 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3249
3250 ClientSocketHandle handle1;
3251 TestCompletionCallback callback;
3252 EXPECT_EQ(
3253 ERR_IO_PENDING,
3254 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3255 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3256 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3257 pool_.get(), NetLogWithSource()));
3258 EXPECT_THAT(callback.WaitForResult(), IsOk());
3259
3260 // No idle sockets, no pending jobs.
3261 EXPECT_EQ(0, pool_->IdleSocketCount());
3262 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3263
3264 // Create a second socket to the same host, but this one will wait.
3265 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3266 ClientSocketHandle handle2;
3267 EXPECT_EQ(
3268 ERR_IO_PENDING,
3269 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3270 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3271 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3272 pool_.get(), NetLogWithSource()));
3273 // No idle sockets, and one connecting job.
3274 EXPECT_EQ(0, pool_->IdleSocketCount());
3275 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3276
3277 // Return the first handle to the pool. This will initiate the delayed
3278 // binding.
3279 handle1.Reset();
3280
3281 base::RunLoop().RunUntilIdle();
3282
3283 // Still no idle sockets, still one pending connect job.
3284 EXPECT_EQ(0, pool_->IdleSocketCount());
3285 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3286
3287 // The second socket connected, even though it was a Waiting Job.
3288 EXPECT_THAT(callback.WaitForResult(), IsOk());
3289
3290 // And we can see there is still one job waiting.
3291 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3292
3293 // Finally, signal the waiting Connect.
3294 client_socket_factory_.SignalJobs();
3295 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3296
3297 base::RunLoop().RunUntilIdle();
3298 }
3299
3300 // Test delayed socket binding when a group is at capacity and one
3301 // of the group's sockets frees up.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingAtGroupCapacity)3302 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
3303 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3304 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3305
3306 ClientSocketHandle handle1;
3307 TestCompletionCallback callback;
3308 EXPECT_EQ(
3309 ERR_IO_PENDING,
3310 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3311 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3312 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3313 pool_.get(), NetLogWithSource()));
3314 EXPECT_THAT(callback.WaitForResult(), IsOk());
3315
3316 // No idle sockets, no pending jobs.
3317 EXPECT_EQ(0, pool_->IdleSocketCount());
3318 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3319
3320 // Create a second socket to the same host, but this one will wait.
3321 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3322 ClientSocketHandle handle2;
3323 EXPECT_EQ(
3324 ERR_IO_PENDING,
3325 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3326 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3327 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3328 pool_.get(), NetLogWithSource()));
3329 // No idle sockets, and one connecting job.
3330 EXPECT_EQ(0, pool_->IdleSocketCount());
3331 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3332
3333 // Return the first handle to the pool. This will initiate the delayed
3334 // binding.
3335 handle1.Reset();
3336
3337 base::RunLoop().RunUntilIdle();
3338
3339 // Still no idle sockets, still one pending connect job.
3340 EXPECT_EQ(0, pool_->IdleSocketCount());
3341 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3342
3343 // The second socket connected, even though it was a Waiting Job.
3344 EXPECT_THAT(callback.WaitForResult(), IsOk());
3345
3346 // And we can see there is still one job waiting.
3347 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3348
3349 // Finally, signal the waiting Connect.
3350 client_socket_factory_.SignalJobs();
3351 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3352
3353 base::RunLoop().RunUntilIdle();
3354 }
3355
3356 // Test out the case where we have one socket connected, one
3357 // connecting, when the first socket finishes and goes idle.
3358 // Although the second connection is pending, the second request
3359 // should complete, by taking the first socket's idle socket.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingAtStall)3360 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3361 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3362 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3363
3364 ClientSocketHandle handle1;
3365 TestCompletionCallback callback;
3366 EXPECT_EQ(
3367 ERR_IO_PENDING,
3368 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3369 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3370 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3371 pool_.get(), NetLogWithSource()));
3372 EXPECT_THAT(callback.WaitForResult(), IsOk());
3373
3374 // No idle sockets, no pending jobs.
3375 EXPECT_EQ(0, pool_->IdleSocketCount());
3376 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3377
3378 // Create a second socket to the same host, but this one will wait.
3379 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3380 ClientSocketHandle handle2;
3381 EXPECT_EQ(
3382 ERR_IO_PENDING,
3383 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3384 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3385 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3386 pool_.get(), NetLogWithSource()));
3387 // No idle sockets, and one connecting job.
3388 EXPECT_EQ(0, pool_->IdleSocketCount());
3389 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3390
3391 // Return the first handle to the pool. This will initiate the delayed
3392 // binding.
3393 handle1.Reset();
3394
3395 base::RunLoop().RunUntilIdle();
3396
3397 // Still no idle sockets, still one pending connect job.
3398 EXPECT_EQ(0, pool_->IdleSocketCount());
3399 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3400
3401 // The second socket connected, even though it was a Waiting Job.
3402 EXPECT_THAT(callback.WaitForResult(), IsOk());
3403
3404 // And we can see there is still one job waiting.
3405 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3406
3407 // Finally, signal the waiting Connect.
3408 client_socket_factory_.SignalJobs();
3409 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3410
3411 base::RunLoop().RunUntilIdle();
3412 }
3413
3414 // Cover the case where on an available socket slot, we have one pending
3415 // request that completes synchronously, thereby making the Group empty.
TEST_F(ClientSocketPoolBaseTest,SynchronouslyProcessOnePendingRequest)3416 TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3417 const int kUnlimitedSockets = 100;
3418 const int kOneSocketPerGroup = 1;
3419 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3420
3421 // Make the first request asynchronous fail.
3422 // This will free up a socket slot later.
3423 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3424
3425 ClientSocketHandle handle1;
3426 TestCompletionCallback callback1;
3427 EXPECT_EQ(
3428 ERR_IO_PENDING,
3429 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3430 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3431 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3432 pool_.get(), NetLogWithSource()));
3433 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3434
3435 // Make the second request synchronously fail. This should make the Group
3436 // empty.
3437 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3438 ClientSocketHandle handle2;
3439 TestCompletionCallback callback2;
3440 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3441 // when created.
3442 EXPECT_EQ(
3443 ERR_IO_PENDING,
3444 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3445 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3446 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3447 pool_.get(), NetLogWithSource()));
3448
3449 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3450
3451 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3452 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3453 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3454 }
3455
TEST_F(ClientSocketPoolBaseTest,PreferUsedSocketToUnusedSocket)3456 TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3457 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3458
3459 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3460
3461 ClientSocketHandle handle1;
3462 TestCompletionCallback callback1;
3463 EXPECT_EQ(
3464 ERR_IO_PENDING,
3465 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3466 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3467 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3468 pool_.get(), NetLogWithSource()));
3469
3470 ClientSocketHandle handle2;
3471 TestCompletionCallback callback2;
3472 EXPECT_EQ(
3473 ERR_IO_PENDING,
3474 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3475 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3476 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3477 pool_.get(), NetLogWithSource()));
3478 ClientSocketHandle handle3;
3479 TestCompletionCallback callback3;
3480 EXPECT_EQ(
3481 ERR_IO_PENDING,
3482 handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3483 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3484 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3485 pool_.get(), NetLogWithSource()));
3486
3487 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3488 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3489 EXPECT_THAT(callback3.WaitForResult(), IsOk());
3490
3491 // Use the socket.
3492 EXPECT_EQ(1, handle1.socket()->Write(nullptr, 1, CompletionOnceCallback(),
3493 TRAFFIC_ANNOTATION_FOR_TESTS));
3494 EXPECT_EQ(1, handle3.socket()->Write(nullptr, 1, CompletionOnceCallback(),
3495 TRAFFIC_ANNOTATION_FOR_TESTS));
3496
3497 handle1.Reset();
3498 handle2.Reset();
3499 handle3.Reset();
3500
3501 EXPECT_EQ(OK, handle1.Init(
3502 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3503 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3504 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3505 pool_.get(), NetLogWithSource()));
3506 EXPECT_EQ(OK, handle2.Init(
3507 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3508 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3509 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3510 pool_.get(), NetLogWithSource()));
3511 EXPECT_EQ(OK, handle3.Init(
3512 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3513 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3514 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3515 pool_.get(), NetLogWithSource()));
3516
3517 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3518 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3519 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3520 }
3521
TEST_F(ClientSocketPoolBaseTest,RequestSockets)3522 TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3523 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3524 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3525
3526 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3527 NetLogWithSource());
3528
3529 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3530 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3531 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3532 TestGroupId("a")));
3533 EXPECT_EQ(2u,
3534 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3535 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3536
3537 ClientSocketHandle handle1;
3538 TestCompletionCallback callback1;
3539 EXPECT_EQ(
3540 ERR_IO_PENDING,
3541 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3542 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3543 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3544 pool_.get(), NetLogWithSource()));
3545
3546 ClientSocketHandle handle2;
3547 TestCompletionCallback callback2;
3548 EXPECT_EQ(
3549 ERR_IO_PENDING,
3550 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3551 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3552 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3553 pool_.get(), NetLogWithSource()));
3554
3555 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3556 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3557 TestGroupId("a")));
3558 EXPECT_EQ(0u,
3559 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3560 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3561
3562 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3563 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3564 handle1.Reset();
3565 handle2.Reset();
3566
3567 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3568 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3569 TestGroupId("a")));
3570 EXPECT_EQ(0u,
3571 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3572 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3573 }
3574
TEST_F(ClientSocketPoolBaseTest,RequestSocketsWhenAlreadyHaveAConnectJob)3575 TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3576 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3577 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3578
3579 ClientSocketHandle handle1;
3580 TestCompletionCallback callback1;
3581 EXPECT_EQ(
3582 ERR_IO_PENDING,
3583 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3584 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3585 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3586 pool_.get(), NetLogWithSource()));
3587
3588 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3589 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3590 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3591 TestGroupId("a")));
3592 EXPECT_EQ(0u,
3593 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3594 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3595
3596 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3597 NetLogWithSource());
3598
3599 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3600 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3601 TestGroupId("a")));
3602 EXPECT_EQ(1u,
3603 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3604 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3605
3606 ClientSocketHandle handle2;
3607 TestCompletionCallback callback2;
3608 EXPECT_EQ(
3609 ERR_IO_PENDING,
3610 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3611 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3612 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3613 pool_.get(), NetLogWithSource()));
3614
3615 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3616 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3617 TestGroupId("a")));
3618 EXPECT_EQ(0u,
3619 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3620 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3621
3622 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3623 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3624 handle1.Reset();
3625 handle2.Reset();
3626
3627 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3628 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3629 TestGroupId("a")));
3630 EXPECT_EQ(0u,
3631 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3632 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3633 }
3634
TEST_F(ClientSocketPoolBaseTest,RequestSocketsWhenAlreadyHaveMultipleConnectJob)3635 TEST_F(ClientSocketPoolBaseTest,
3636 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3637 CreatePool(4, 4);
3638 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3639
3640 ClientSocketHandle handle1;
3641 TestCompletionCallback callback1;
3642 EXPECT_EQ(
3643 ERR_IO_PENDING,
3644 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3645 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3646 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3647 pool_.get(), NetLogWithSource()));
3648
3649 ClientSocketHandle handle2;
3650 TestCompletionCallback callback2;
3651 EXPECT_EQ(
3652 ERR_IO_PENDING,
3653 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3654 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3655 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3656 pool_.get(), NetLogWithSource()));
3657
3658 ClientSocketHandle handle3;
3659 TestCompletionCallback callback3;
3660 EXPECT_EQ(
3661 ERR_IO_PENDING,
3662 handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3663 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3664 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3665 pool_.get(), NetLogWithSource()));
3666
3667 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3668 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3669 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3670 TestGroupId("a")));
3671 EXPECT_EQ(0u,
3672 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3673 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3674
3675 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3676 NetLogWithSource());
3677
3678 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3679 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3680 TestGroupId("a")));
3681 EXPECT_EQ(0u,
3682 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3683 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3684
3685 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3686 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3687 EXPECT_THAT(callback3.WaitForResult(), IsOk());
3688 handle1.Reset();
3689 handle2.Reset();
3690 handle3.Reset();
3691
3692 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3693 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3694 TestGroupId("a")));
3695 EXPECT_EQ(0u,
3696 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3697 EXPECT_EQ(3u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3698 }
3699
TEST_F(ClientSocketPoolBaseTest,RequestSocketsAtMaxSocketLimit)3700 TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3701 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3702 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3703
3704 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3705
3706 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3707 kDefaultMaxSockets, NetLogWithSource());
3708
3709 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3710 EXPECT_EQ(kDefaultMaxSockets,
3711 static_cast<int>(
3712 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3713 EXPECT_EQ(
3714 kDefaultMaxSockets,
3715 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3716 TestGroupId("a"))));
3717 EXPECT_EQ(kDefaultMaxSockets,
3718 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3719 TestGroupId("a"))));
3720
3721 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
3722
3723 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3724 kDefaultMaxSockets, NetLogWithSource());
3725
3726 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
3727 }
3728
TEST_F(ClientSocketPoolBaseTest,RequestSocketsHitMaxSocketLimit)3729 TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3730 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3731 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3732
3733 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3734
3735 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3736 kDefaultMaxSockets - 1, NetLogWithSource());
3737
3738 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3739 EXPECT_EQ(kDefaultMaxSockets - 1,
3740 static_cast<int>(
3741 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3742 EXPECT_EQ(
3743 kDefaultMaxSockets - 1,
3744 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3745 TestGroupId("a"))));
3746 EXPECT_EQ(kDefaultMaxSockets - 1,
3747 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3748 TestGroupId("a"))));
3749 EXPECT_FALSE(pool_->IsStalled());
3750
3751 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
3752
3753 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3754 kDefaultMaxSockets, NetLogWithSource());
3755
3756 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
3757 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
3758 EXPECT_FALSE(pool_->IsStalled());
3759 }
3760
TEST_F(ClientSocketPoolBaseTest,RequestSocketsCountIdleSockets)3761 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3762 CreatePool(4, 4);
3763 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3764
3765 ClientSocketHandle handle1;
3766 TestCompletionCallback callback1;
3767 EXPECT_EQ(
3768 ERR_IO_PENDING,
3769 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3770 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3771 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3772 pool_.get(), NetLogWithSource()));
3773 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3774 handle1.Reset();
3775
3776 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3777 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3778 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3779 TestGroupId("a")));
3780 EXPECT_EQ(0u,
3781 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3782 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3783
3784 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3785 NetLogWithSource());
3786
3787 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3788 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3789 TestGroupId("a")));
3790 EXPECT_EQ(1u,
3791 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3792 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3793 }
3794
TEST_F(ClientSocketPoolBaseTest,RequestSocketsCountActiveSockets)3795 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3796 CreatePool(4, 4);
3797 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3798
3799 ClientSocketHandle handle1;
3800 TestCompletionCallback callback1;
3801 EXPECT_EQ(
3802 ERR_IO_PENDING,
3803 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3804 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3805 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3806 pool_.get(), NetLogWithSource()));
3807 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3808
3809 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3810 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3811 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3812 TestGroupId("a")));
3813 EXPECT_EQ(0u,
3814 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3815 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3816 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3817
3818 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3819 NetLogWithSource());
3820
3821 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3822 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3823 TestGroupId("a")));
3824 EXPECT_EQ(1u,
3825 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3826 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3827 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3828 }
3829
TEST_F(ClientSocketPoolBaseTest,RequestSocketsSynchronous)3830 TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3831 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3832 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3833
3834 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3835 kDefaultMaxSocketsPerGroup, NetLogWithSource());
3836
3837 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3838 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3839 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3840 TestGroupId("a")));
3841 EXPECT_EQ(0u,
3842 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3843 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
3844 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("a"))));
3845
3846 pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt,
3847 kDefaultMaxSocketsPerGroup, NetLogWithSource());
3848
3849 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
3850 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3851 TestGroupId("b")));
3852 EXPECT_EQ(0u,
3853 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
3854 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
3855 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("b"))));
3856 }
3857
TEST_F(ClientSocketPoolBaseTest,RequestSocketsSynchronousError)3858 TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3859 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3860 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3861
3862 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3863 kDefaultMaxSocketsPerGroup, NetLogWithSource());
3864
3865 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3866
3867 connect_job_factory_->set_job_type(
3868 TestConnectJob::kMockAdditionalErrorStateJob);
3869 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt,
3870 kDefaultMaxSocketsPerGroup, NetLogWithSource());
3871
3872 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3873 }
3874
TEST_F(ClientSocketPoolBaseTest,RequestSocketsMultipleTimesDoesNothing)3875 TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3876 CreatePool(4, 4);
3877 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3878
3879 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3880 NetLogWithSource());
3881
3882 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3883 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3884 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3885 TestGroupId("a")));
3886 EXPECT_EQ(2u,
3887 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3888 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3889 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3890
3891 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3892 NetLogWithSource());
3893 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3894 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3895 TestGroupId("a")));
3896 EXPECT_EQ(2u,
3897 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3898 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3899 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3900
3901 ClientSocketHandle handle1;
3902 TestCompletionCallback callback1;
3903 EXPECT_EQ(
3904 ERR_IO_PENDING,
3905 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3906 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3907 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3908 pool_.get(), NetLogWithSource()));
3909
3910 client_socket_factory_.SignalJob(0);
3911 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3912
3913 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3914 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3915 TestGroupId("a")));
3916 EXPECT_EQ(1u,
3917 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3918 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3919 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3920
3921 ClientSocketHandle handle2;
3922 TestCompletionCallback callback2;
3923 EXPECT_EQ(
3924 ERR_IO_PENDING,
3925 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
3926 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3927 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3928 pool_.get(), NetLogWithSource()));
3929 client_socket_factory_.SignalJob(0);
3930 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3931
3932 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3933 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3934 TestGroupId("a")));
3935 EXPECT_EQ(0u,
3936 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3937 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3938 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3939
3940 handle1.Reset();
3941 handle2.Reset();
3942
3943 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3944 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3945 TestGroupId("a")));
3946 EXPECT_EQ(0u,
3947 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3948 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3949 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3950
3951 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3952 NetLogWithSource());
3953 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3954 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3955 TestGroupId("a")));
3956 EXPECT_EQ(0u,
3957 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3958 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3959 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3960 }
3961
TEST_F(ClientSocketPoolBaseTest,RequestSocketsDifferentNumSockets)3962 TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3963 CreatePool(4, 4);
3964 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3965
3966 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3967 NetLogWithSource());
3968
3969 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3970 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3971 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3972 TestGroupId("a")));
3973 EXPECT_EQ(1u,
3974 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3975 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3976
3977 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
3978 NetLogWithSource());
3979 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3980 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3981 TestGroupId("a")));
3982 EXPECT_EQ(2u,
3983 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3984 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3985
3986 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 3,
3987 NetLogWithSource());
3988 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3989 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3990 TestGroupId("a")));
3991 EXPECT_EQ(3u,
3992 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3993 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3994
3995 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
3996 NetLogWithSource());
3997 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3998 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3999 TestGroupId("a")));
4000 EXPECT_EQ(3u,
4001 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4002 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4003 }
4004
TEST_F(ClientSocketPoolBaseTest,PreconnectJobsTakenByNormalRequests)4005 TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
4006 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4007 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4008
4009 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4010 NetLogWithSource());
4011
4012 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4013 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4014 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4015 TestGroupId("a")));
4016 EXPECT_EQ(1u,
4017 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4018 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4019
4020 ClientSocketHandle handle1;
4021 TestCompletionCallback callback1;
4022 EXPECT_EQ(
4023 ERR_IO_PENDING,
4024 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4025 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4026 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4027 pool_.get(), NetLogWithSource()));
4028
4029 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4030 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4031 TestGroupId("a")));
4032 EXPECT_EQ(0u,
4033 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4034 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4035
4036 client_socket_factory_.SignalJobs();
4037 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4038
4039 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4040 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4041 TestGroupId("a")));
4042 EXPECT_EQ(0u,
4043 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4044 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4045 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4046
4047 // Make sure if a preconnected socket is not fully connected when a request
4048 // starts, it has a connect start time.
4049 TestLoadTimingInfoConnectedNotReused(handle1);
4050 handle1.Reset();
4051
4052 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4053 }
4054
4055 // Checks that fully connected preconnect jobs have no connect times, and are
4056 // marked as reused.
TEST_F(ClientSocketPoolBaseTest,ConnectedPreconnectJobsHaveNoConnectTimes)4057 TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
4058 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4059 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4060 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4061 NetLogWithSource());
4062
4063 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4064 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4065 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4066 TestGroupId("a")));
4067 EXPECT_EQ(0u,
4068 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4069 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4070
4071 ClientSocketHandle handle;
4072 TestCompletionCallback callback;
4073 EXPECT_EQ(OK, handle.Init(
4074 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4075 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4076 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4077 pool_.get(), NetLogWithSource()));
4078
4079 // Make sure the idle socket was used.
4080 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4081
4082 TestLoadTimingInfoConnectedReused(handle);
4083 handle.Reset();
4084 TestLoadTimingInfoNotConnected(handle);
4085 }
4086
4087 // http://crbug.com/64940 regression test.
TEST_F(ClientSocketPoolBaseTest,PreconnectClosesIdleSocketRemovesGroup)4088 TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
4089 const int kMaxTotalSockets = 3;
4090 const int kMaxSocketsPerGroup = 2;
4091 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
4092 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4093
4094 // Note that group id ordering matters here. "a" comes before "b", so
4095 // CloseOneIdleSocket() will try to close "a"'s idle socket.
4096
4097 // Set up one idle socket in "a".
4098 ClientSocketHandle handle1;
4099 TestCompletionCallback callback1;
4100 EXPECT_EQ(
4101 ERR_IO_PENDING,
4102 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4103 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4104 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4105 pool_.get(), NetLogWithSource()));
4106 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4107 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4108 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4109 TestGroupId("a")));
4110 EXPECT_EQ(0u,
4111 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4112 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4113
4114 client_socket_factory_.SignalJobs();
4115 ASSERT_THAT(callback1.WaitForResult(), IsOk());
4116 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4117 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4118 TestGroupId("a")));
4119 EXPECT_EQ(0u,
4120 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4121 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4122
4123 handle1.Reset();
4124 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4125
4126 // Set up two active sockets in "b".
4127 ClientSocketHandle handle2;
4128 TestCompletionCallback callback2;
4129 EXPECT_EQ(
4130 ERR_IO_PENDING,
4131 handle1.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
4132 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4133 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4134 pool_.get(), NetLogWithSource()));
4135 EXPECT_EQ(
4136 ERR_IO_PENDING,
4137 handle2.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY,
4138 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4139 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4140 pool_.get(), NetLogWithSource()));
4141
4142 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
4143 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4144 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4145 TestGroupId("b")));
4146 EXPECT_EQ(0u,
4147 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4148 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4149
4150 client_socket_factory_.SignalJobs();
4151 ASSERT_THAT(callback1.WaitForResult(), IsOk());
4152 ASSERT_THAT(callback2.WaitForResult(), IsOk());
4153 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4154 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4155 TestGroupId("b")));
4156 EXPECT_EQ(0u,
4157 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4158 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
4159
4160 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
4161 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
4162 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
4163 // sockets for "a", and "b" should still have 2 active sockets.
4164
4165 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
4166 NetLogWithSource());
4167 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4168 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4169 TestGroupId("a")));
4170 EXPECT_EQ(0u,
4171 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4172 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4173 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4174 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4175 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4176 TestGroupId("b")));
4177 EXPECT_EQ(0u,
4178 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4179 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4180 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
4181
4182 // Now release the 2 active sockets for "b". This will give us 1 idle socket
4183 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
4184 // "a" should result in closing 1 for "b".
4185 handle1.Reset();
4186 handle2.Reset();
4187 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4188 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
4189
4190 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2,
4191 NetLogWithSource());
4192 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4193 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4194 TestGroupId("a")));
4195 EXPECT_EQ(1u,
4196 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4197 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4198 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4199 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4200 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4201 TestGroupId("b")));
4202 EXPECT_EQ(0u,
4203 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4204 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4205 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
4206 }
4207
TEST_F(ClientSocketPoolBaseTest,PreconnectWithoutBackupJob)4208 TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
4209 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4210 true /* enable_backup_connect_jobs */);
4211
4212 // Make the ConnectJob hang until it times out, shorten the timeout.
4213 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4214 connect_job_factory_->set_timeout_duration(
4215 base::TimeDelta::FromMilliseconds(500));
4216 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4217 NetLogWithSource());
4218 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4219 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4220 TestGroupId("a")));
4221 EXPECT_EQ(1u,
4222 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4223 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4224
4225 // Verify the backup timer doesn't create a backup job, by making
4226 // the backup job a pending job instead of a waiting job, so it
4227 // *would* complete if it were created.
4228 base::RunLoop loop;
4229 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4230 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
4231 FROM_HERE, loop.QuitClosure(), base::TimeDelta::FromSeconds(1));
4232 loop.Run();
4233 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
4234 }
4235
TEST_F(ClientSocketPoolBaseTest,PreconnectWithBackupJob)4236 TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
4237 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4238 true /* enable_backup_connect_jobs */);
4239
4240 // Make the ConnectJob hang forever.
4241 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4242 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4243 NetLogWithSource());
4244 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4245 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4246 TestGroupId("a")));
4247 EXPECT_EQ(1u,
4248 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4249 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4250 base::RunLoop().RunUntilIdle();
4251
4252 // Make the backup job be a pending job, so it completes normally.
4253 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4254 ClientSocketHandle handle;
4255 TestCompletionCallback callback;
4256 EXPECT_EQ(
4257 ERR_IO_PENDING,
4258 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4259 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4260 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4261 pool_.get(), NetLogWithSource()));
4262 // Timer has started, but the backup connect job shouldn't be created yet.
4263 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4264 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4265 TestGroupId("a")));
4266 EXPECT_EQ(0u,
4267 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4268 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4269 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4270 ASSERT_THAT(callback.WaitForResult(), IsOk());
4271
4272 // The hung connect job should still be there, but everything else should be
4273 // complete.
4274 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4275 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4276 TestGroupId("a")));
4277 EXPECT_EQ(1u,
4278 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4279 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4280 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4281 }
4282
4283 // Tests that a preconnect that starts out with unread data can still be used.
4284 // http://crbug.com/334467
TEST_F(ClientSocketPoolBaseTest,PreconnectWithUnreadData)4285 TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
4286 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4287 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
4288
4289 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4290 NetLogWithSource());
4291
4292 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4293 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4294 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4295 TestGroupId("a")));
4296 EXPECT_EQ(0u,
4297 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4298 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4299
4300 // Fail future jobs to be sure that handle receives the preconnected socket
4301 // rather than closing it and making a new one.
4302 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
4303 ClientSocketHandle handle;
4304 TestCompletionCallback callback;
4305 EXPECT_EQ(OK, handle.Init(
4306 TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4307 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4308 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4309 pool_.get(), NetLogWithSource()));
4310
4311 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4312 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4313 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4314 TestGroupId("a")));
4315 EXPECT_EQ(0u,
4316 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4317 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4318 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4319
4320 // Drain the pending read.
4321 EXPECT_EQ(1, handle.socket()->Read(nullptr, 1, CompletionOnceCallback()));
4322
4323 TestLoadTimingInfoConnectedReused(handle);
4324 handle.Reset();
4325
4326 // The socket should be usable now that it's idle again.
4327 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4328 }
4329
TEST_F(ClientSocketPoolBaseTest,RequestGetsAssignedJob)4330 TEST_F(ClientSocketPoolBaseTest, RequestGetsAssignedJob) {
4331 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4332 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4333
4334 ClientSocketHandle handle1;
4335 TestCompletionCallback callback1;
4336 EXPECT_EQ(
4337 ERR_IO_PENDING,
4338 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4339 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4340 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4341 pool_.get(), NetLogWithSource()));
4342
4343 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4344 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4345 TestGroupId("a")));
4346 EXPECT_EQ(0u,
4347 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4348 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4349
4350 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4351 &handle1));
4352 }
4353
TEST_F(ClientSocketPoolBaseTest,MultipleRequestsGetAssignedJobs)4354 TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) {
4355 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4356 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4357
4358 ClientSocketHandle handle1;
4359 TestCompletionCallback callback1;
4360 EXPECT_EQ(
4361 ERR_IO_PENDING,
4362 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4363 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4364 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4365 pool_.get(), NetLogWithSource()));
4366
4367 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4368 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4369 TestGroupId("a")));
4370 EXPECT_EQ(0u,
4371 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4372 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4373
4374 ClientSocketHandle handle2;
4375 TestCompletionCallback callback2;
4376 EXPECT_EQ(
4377 ERR_IO_PENDING,
4378 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4379 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4380 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4381 pool_.get(), NetLogWithSource()));
4382
4383 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4384 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4385 TestGroupId("a")));
4386 EXPECT_EQ(0u,
4387 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4388 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4389
4390 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4391 &handle1));
4392 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4393 &handle2));
4394
4395 // One job completes. The other request should still have its job.
4396 client_socket_factory_.SignalJob(0);
4397 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4398
4399 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4400 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4401 TestGroupId("a")));
4402 EXPECT_EQ(0u,
4403 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4404 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4405 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4406
4407 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4408 &handle2));
4409 }
4410
TEST_F(ClientSocketPoolBaseTest,PreconnectJobGetsAssignedToRequest)4411 TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) {
4412 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4413 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4414
4415 pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1,
4416 NetLogWithSource());
4417
4418 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4419 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4420 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4421 TestGroupId("a")));
4422 EXPECT_EQ(1u,
4423 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4424 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4425
4426 ClientSocketHandle handle1;
4427 TestCompletionCallback callback1;
4428 EXPECT_EQ(
4429 ERR_IO_PENDING,
4430 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4431 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4432 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4433 pool_.get(), NetLogWithSource()));
4434
4435 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4436 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4437 TestGroupId("a")));
4438 EXPECT_EQ(0u,
4439 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4440 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4441
4442 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4443 &handle1));
4444 }
4445
TEST_F(ClientSocketPoolBaseTest,HigherPriorityRequestStealsJob)4446 TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) {
4447 CreatePool(kDefaultMaxSockets, 1);
4448 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4449
4450 ClientSocketHandle handle1;
4451 TestCompletionCallback callback1;
4452 EXPECT_EQ(
4453 ERR_IO_PENDING,
4454 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4455 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4456 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4457 pool_.get(), NetLogWithSource()));
4458
4459 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4460 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4461 TestGroupId("a")));
4462 EXPECT_EQ(0u,
4463 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4464 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4465
4466 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4467 &handle1));
4468
4469 // Insert a higher priority request
4470 ClientSocketHandle handle2;
4471 TestCompletionCallback callback2;
4472 EXPECT_EQ(
4473 ERR_IO_PENDING,
4474 handle2.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4475 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4476 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4477 pool_.get(), NetLogWithSource()));
4478
4479 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4480 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4481 TestGroupId("a")));
4482 EXPECT_EQ(0u,
4483 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4484 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4485
4486 // The highest priority request should steal the job from the default priority
4487 // request.
4488 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4489 &handle2));
4490 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4491 &handle1));
4492 }
4493
TEST_F(ClientSocketPoolBaseTest,RequestStealsJobFromLowestRequestWithJob)4494 TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) {
4495 CreatePool(3, 3);
4496 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4497
4498 ClientSocketHandle handle_lowest;
4499 TestCompletionCallback callback_lowest;
4500 EXPECT_EQ(
4501 ERR_IO_PENDING,
4502 handle_lowest.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
4503 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4504 callback_lowest.callback(),
4505 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4506 NetLogWithSource()));
4507
4508 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4509 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4510 TestGroupId("a")));
4511 EXPECT_EQ(0u,
4512 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4513 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4514
4515 ClientSocketHandle handle_highest;
4516 TestCompletionCallback callback_highest;
4517 EXPECT_EQ(
4518 ERR_IO_PENDING,
4519 handle_highest.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4520 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4521 callback_highest.callback(),
4522 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4523 NetLogWithSource()));
4524
4525 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4526 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4527 TestGroupId("a")));
4528 EXPECT_EQ(0u,
4529 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4530 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4531
4532 ClientSocketHandle handle_low;
4533 TestCompletionCallback callback_low;
4534 EXPECT_EQ(ERR_IO_PENDING,
4535 handle_low.Init(
4536 TestGroupId("a"), params_, base::nullopt, LOW, SocketTag(),
4537 ClientSocketPool::RespectLimits::ENABLED,
4538 callback_low.callback(), ClientSocketPool::ProxyAuthCallback(),
4539 pool_.get(), NetLogWithSource()));
4540
4541 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4542 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4543 TestGroupId("a")));
4544 EXPECT_EQ(0u,
4545 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4546 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4547
4548 ClientSocketHandle handle_lowest2;
4549 TestCompletionCallback callback_lowest2;
4550 EXPECT_EQ(
4551 ERR_IO_PENDING,
4552 handle_lowest2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST,
4553 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4554 callback_lowest2.callback(),
4555 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4556 NetLogWithSource()));
4557
4558 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4559 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4560 TestGroupId("a")));
4561 EXPECT_EQ(0u,
4562 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4563 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4564
4565 // The top three requests in the queue should have jobs.
4566 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4567 &handle_highest));
4568 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4569 &handle_low));
4570 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4571 &handle_lowest));
4572 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4573 TestGroupId("a"), &handle_lowest2));
4574
4575 // Add another request with medium priority. It should steal the job from the
4576 // lowest priority request with a job.
4577 ClientSocketHandle handle_medium;
4578 TestCompletionCallback callback_medium;
4579 EXPECT_EQ(
4580 ERR_IO_PENDING,
4581 handle_medium.Init(TestGroupId("a"), params_, base::nullopt, MEDIUM,
4582 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4583 callback_medium.callback(),
4584 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4585 NetLogWithSource()));
4586
4587 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4588 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4589 TestGroupId("a")));
4590 EXPECT_EQ(0u,
4591 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4592 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4593 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4594 &handle_highest));
4595 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4596 &handle_medium));
4597 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4598 &handle_low));
4599 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4600 &handle_lowest));
4601 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4602 TestGroupId("a"), &handle_lowest2));
4603 }
4604
TEST_F(ClientSocketPoolBaseTest,ReprioritizeRequestStealsJob)4605 TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) {
4606 CreatePool(kDefaultMaxSockets, 1);
4607 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4608
4609 ClientSocketHandle handle1;
4610 TestCompletionCallback callback1;
4611 EXPECT_EQ(
4612 ERR_IO_PENDING,
4613 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4614 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4615 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4616 pool_.get(), NetLogWithSource()));
4617
4618 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4619 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4620 TestGroupId("a")));
4621 EXPECT_EQ(0u,
4622 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4623 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4624
4625 ClientSocketHandle handle2;
4626 TestCompletionCallback callback2;
4627 EXPECT_EQ(
4628 ERR_IO_PENDING,
4629 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4630 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4631 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4632 pool_.get(), NetLogWithSource()));
4633
4634 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4635 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4636 TestGroupId("a")));
4637 EXPECT_EQ(0u,
4638 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4639 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4640
4641 // The second request doesn't get a job because we are at the limit.
4642 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4643 &handle1));
4644 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4645 &handle2));
4646
4647 // Reprioritizing the second request places it above the first, and it steals
4648 // the job from the first request.
4649 pool_->SetPriority(TestGroupId("a"), &handle2, HIGHEST);
4650 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4651 &handle2));
4652 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4653 &handle1));
4654 }
4655
TEST_F(ClientSocketPoolBaseTest,CancelRequestReassignsJob)4656 TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) {
4657 CreatePool(kDefaultMaxSockets, 1);
4658 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4659
4660 ClientSocketHandle handle1;
4661 TestCompletionCallback callback1;
4662 EXPECT_EQ(
4663 ERR_IO_PENDING,
4664 handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4665 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4666 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4667 pool_.get(), NetLogWithSource()));
4668
4669 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4670 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4671 TestGroupId("a")));
4672 EXPECT_EQ(0u,
4673 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4674 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4675
4676 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4677 &handle1));
4678
4679 ClientSocketHandle handle2;
4680 TestCompletionCallback callback2;
4681 EXPECT_EQ(
4682 ERR_IO_PENDING,
4683 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4684 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4685 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4686 pool_.get(), NetLogWithSource()));
4687
4688 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4689 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4690 TestGroupId("a")));
4691 EXPECT_EQ(0u,
4692 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4693 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4694
4695 // The second request doesn't get a job because we are the limit.
4696 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4697 &handle1));
4698 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4699 &handle2));
4700
4701 // The second request should get a job upon cancelling the first request.
4702 handle1.Reset();
4703 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4704 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4705 TestGroupId("a")));
4706 EXPECT_EQ(0u,
4707 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4708 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4709
4710 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4711 &handle2));
4712 }
4713
TEST_F(ClientSocketPoolBaseTest,JobCompletionReassignsJob)4714 TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) {
4715 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4716 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4717
4718 ClientSocketHandle handle1;
4719 TestCompletionCallback callback1;
4720 EXPECT_EQ(
4721 ERR_IO_PENDING,
4722 handle1.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST,
4723 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4724 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4725 pool_.get(), NetLogWithSource()));
4726
4727 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4728 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4729 TestGroupId("a")));
4730 EXPECT_EQ(0u,
4731 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4732 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4733
4734 ClientSocketHandle handle2;
4735 TestCompletionCallback callback2;
4736 EXPECT_EQ(
4737 ERR_IO_PENDING,
4738 handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4739 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4740 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4741 pool_.get(), NetLogWithSource()));
4742
4743 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4744 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4745 TestGroupId("a")));
4746 EXPECT_EQ(0u,
4747 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4748 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4749
4750 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4751 &handle1));
4752 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4753 &handle2));
4754
4755 // The lower-priority job completes first. The higher-priority request should
4756 // get the socket, and the lower-priority request should get the remaining
4757 // job.
4758 client_socket_factory_.SignalJob(1);
4759 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4760 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4761 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4762 TestGroupId("a")));
4763 EXPECT_EQ(0u,
4764 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4765 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4766 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4767 EXPECT_TRUE(handle1.socket());
4768 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4769 &handle2));
4770 }
4771
4772 class MockLayeredPool : public HigherLayeredPool {
4773 public:
MockLayeredPool(TransportClientSocketPool * pool,const ClientSocketPool::GroupId & group_id)4774 MockLayeredPool(TransportClientSocketPool* pool,
4775 const ClientSocketPool::GroupId& group_id)
4776 : pool_(pool), group_id_(group_id), can_release_connection_(true) {
4777 pool_->AddHigherLayeredPool(this);
4778 }
4779
~MockLayeredPool()4780 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
4781
RequestSocket(TransportClientSocketPool * pool)4782 int RequestSocket(TransportClientSocketPool* pool) {
4783 return handle_.Init(
4784 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
4785 base::nullopt, DEFAULT_PRIORITY, SocketTag(),
4786 ClientSocketPool::RespectLimits::ENABLED, callback_.callback(),
4787 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
4788 }
4789
RequestSocketWithoutLimits(TransportClientSocketPool * pool)4790 int RequestSocketWithoutLimits(TransportClientSocketPool* pool) {
4791 return handle_.Init(
4792 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
4793 base::nullopt, MAXIMUM_PRIORITY, SocketTag(),
4794 ClientSocketPool::RespectLimits::DISABLED, callback_.callback(),
4795 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
4796 }
4797
ReleaseOneConnection()4798 bool ReleaseOneConnection() {
4799 if (!handle_.is_initialized() || !can_release_connection_) {
4800 return false;
4801 }
4802 handle_.socket()->Disconnect();
4803 handle_.Reset();
4804 return true;
4805 }
4806
set_can_release_connection(bool can_release_connection)4807 void set_can_release_connection(bool can_release_connection) {
4808 can_release_connection_ = can_release_connection;
4809 }
4810
4811 MOCK_METHOD0(CloseOneIdleConnection, bool());
4812
4813 private:
4814 TransportClientSocketPool* const pool_;
4815 ClientSocketHandle handle_;
4816 TestCompletionCallback callback_;
4817 const ClientSocketPool::GroupId group_id_;
4818 bool can_release_connection_;
4819 };
4820
4821 // Tests the basic case of closing an idle socket in a higher layered pool when
4822 // a new request is issued and the lower layer pool is stalled.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolWhenNeeded)4823 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
4824 CreatePool(1, 1);
4825 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4826
4827 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
4828 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4829 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4830 .WillOnce(Invoke(&mock_layered_pool,
4831 &MockLayeredPool::ReleaseOneConnection));
4832 ClientSocketHandle handle;
4833 TestCompletionCallback callback;
4834 EXPECT_EQ(
4835 ERR_IO_PENDING,
4836 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4837 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4838 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4839 pool_.get(), NetLogWithSource()));
4840 EXPECT_THAT(callback.WaitForResult(), IsOk());
4841 }
4842
4843 // Tests the case that trying to close an idle socket in a higher layered pool
4844 // fails.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolWhenNeededFails)4845 TEST_F(ClientSocketPoolBaseTest,
4846 CloseIdleSocketsHeldByLayeredPoolWhenNeededFails) {
4847 CreatePool(1, 1);
4848 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4849
4850 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
4851 mock_layered_pool.set_can_release_connection(false);
4852 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4853 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4854 .WillOnce(Invoke(&mock_layered_pool,
4855 &MockLayeredPool::ReleaseOneConnection));
4856 ClientSocketHandle handle;
4857 TestCompletionCallback callback;
4858 EXPECT_EQ(
4859 ERR_IO_PENDING,
4860 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
4861 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4862 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4863 pool_.get(), NetLogWithSource()));
4864 base::RunLoop().RunUntilIdle();
4865 EXPECT_FALSE(callback.have_result());
4866 }
4867
4868 // Same as above, but the idle socket is in the same group as the stalled
4869 // socket, and closes the only other request in its group when closing requests
4870 // in higher layered pools. This generally shouldn't happen, but it may be
4871 // possible if a higher level pool issues a request and the request is
4872 // subsequently cancelled. Even if it's not possible, best not to crash.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup)4873 TEST_F(ClientSocketPoolBaseTest,
4874 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
4875 CreatePool(2, 2);
4876 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4877
4878 // Need a socket in another group for the pool to be stalled (If a group
4879 // has the maximum number of connections already, it's not stalled).
4880 ClientSocketHandle handle1;
4881 TestCompletionCallback callback1;
4882 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4883 DEFAULT_PRIORITY, SocketTag(),
4884 ClientSocketPool::RespectLimits::ENABLED,
4885 callback1.callback(),
4886 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4887 NetLogWithSource()));
4888
4889 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
4890 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4891 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4892 .WillOnce(Invoke(&mock_layered_pool,
4893 &MockLayeredPool::ReleaseOneConnection));
4894 ClientSocketHandle handle;
4895 TestCompletionCallback callback2;
4896 EXPECT_EQ(ERR_IO_PENDING,
4897 handle.Init(
4898 TestGroupId("group2"), params_, base::nullopt, DEFAULT_PRIORITY,
4899 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4900 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4901 pool_.get(), NetLogWithSource()));
4902 EXPECT_THAT(callback2.WaitForResult(), IsOk());
4903 }
4904
4905 // Tests the case when an idle socket can be closed when a new request is
4906 // issued, and the new request belongs to a group that was previously stalled.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded)4907 TEST_F(ClientSocketPoolBaseTest,
4908 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
4909 CreatePool(2, 2);
4910 std::list<TestConnectJob::JobType> job_types;
4911 job_types.push_back(TestConnectJob::kMockJob);
4912 job_types.push_back(TestConnectJob::kMockJob);
4913 job_types.push_back(TestConnectJob::kMockJob);
4914 job_types.push_back(TestConnectJob::kMockJob);
4915 connect_job_factory_->set_job_types(&job_types);
4916
4917 ClientSocketHandle handle1;
4918 TestCompletionCallback callback1;
4919 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4920 DEFAULT_PRIORITY, SocketTag(),
4921 ClientSocketPool::RespectLimits::ENABLED,
4922 callback1.callback(),
4923 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4924 NetLogWithSource()));
4925
4926 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
4927 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4928 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4929 .WillRepeatedly(Invoke(&mock_layered_pool,
4930 &MockLayeredPool::ReleaseOneConnection));
4931 mock_layered_pool.set_can_release_connection(false);
4932
4933 // The third request is made when the socket pool is in a stalled state.
4934 ClientSocketHandle handle3;
4935 TestCompletionCallback callback3;
4936 EXPECT_EQ(ERR_IO_PENDING,
4937 handle3.Init(
4938 TestGroupId("group3"), params_, base::nullopt, DEFAULT_PRIORITY,
4939 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4940 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
4941 pool_.get(), NetLogWithSource()));
4942
4943 base::RunLoop().RunUntilIdle();
4944 EXPECT_FALSE(callback3.have_result());
4945
4946 // The fourth request is made when the pool is no longer stalled. The third
4947 // request should be serviced first, since it was issued first and has the
4948 // same priority.
4949 mock_layered_pool.set_can_release_connection(true);
4950 ClientSocketHandle handle4;
4951 TestCompletionCallback callback4;
4952 EXPECT_EQ(ERR_IO_PENDING,
4953 handle4.Init(
4954 TestGroupId("group3"), params_, base::nullopt, DEFAULT_PRIORITY,
4955 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4956 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
4957 pool_.get(), NetLogWithSource()));
4958 EXPECT_THAT(callback3.WaitForResult(), IsOk());
4959 EXPECT_FALSE(callback4.have_result());
4960
4961 // Closing a handle should free up another socket slot.
4962 handle1.Reset();
4963 EXPECT_THAT(callback4.WaitForResult(), IsOk());
4964 }
4965
4966 // Tests the case when an idle socket can be closed when a new request is
4967 // issued, and the new request belongs to a group that was previously stalled.
4968 //
4969 // The two differences from the above test are that the stalled requests are not
4970 // in the same group as the layered pool's request, and the the fourth request
4971 // has a higher priority than the third one, so gets a socket first.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2)4972 TEST_F(ClientSocketPoolBaseTest,
4973 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
4974 CreatePool(2, 2);
4975 std::list<TestConnectJob::JobType> job_types;
4976 job_types.push_back(TestConnectJob::kMockJob);
4977 job_types.push_back(TestConnectJob::kMockJob);
4978 job_types.push_back(TestConnectJob::kMockJob);
4979 job_types.push_back(TestConnectJob::kMockJob);
4980 connect_job_factory_->set_job_types(&job_types);
4981
4982 ClientSocketHandle handle1;
4983 TestCompletionCallback callback1;
4984 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt,
4985 DEFAULT_PRIORITY, SocketTag(),
4986 ClientSocketPool::RespectLimits::ENABLED,
4987 callback1.callback(),
4988 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4989 NetLogWithSource()));
4990
4991 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
4992 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4993 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4994 .WillRepeatedly(Invoke(&mock_layered_pool,
4995 &MockLayeredPool::ReleaseOneConnection));
4996 mock_layered_pool.set_can_release_connection(false);
4997
4998 // The third request is made when the socket pool is in a stalled state.
4999 ClientSocketHandle handle3;
5000 TestCompletionCallback callback3;
5001 EXPECT_EQ(
5002 ERR_IO_PENDING,
5003 handle3.Init(TestGroupId("group3"), params_, base::nullopt, MEDIUM,
5004 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5005 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
5006 pool_.get(), NetLogWithSource()));
5007
5008 base::RunLoop().RunUntilIdle();
5009 EXPECT_FALSE(callback3.have_result());
5010
5011 // The fourth request is made when the pool is no longer stalled. This
5012 // request has a higher priority than the third request, so is serviced first.
5013 mock_layered_pool.set_can_release_connection(true);
5014 ClientSocketHandle handle4;
5015 TestCompletionCallback callback4;
5016 EXPECT_EQ(
5017 ERR_IO_PENDING,
5018 handle4.Init(TestGroupId("group3"), params_, base::nullopt, HIGHEST,
5019 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5020 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
5021 pool_.get(), NetLogWithSource()));
5022 EXPECT_THAT(callback4.WaitForResult(), IsOk());
5023 EXPECT_FALSE(callback3.have_result());
5024
5025 // Closing a handle should free up another socket slot.
5026 handle1.Reset();
5027 EXPECT_THAT(callback3.WaitForResult(), IsOk());
5028 }
5029
TEST_F(ClientSocketPoolBaseTest,CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded)5030 TEST_F(ClientSocketPoolBaseTest,
5031 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
5032 CreatePool(1, 1);
5033 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
5034
5035 MockLayeredPool mock_layered_pool1(pool_.get(), TestGroupId("foo"));
5036 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
5037 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
5038 .WillRepeatedly(Invoke(&mock_layered_pool1,
5039 &MockLayeredPool::ReleaseOneConnection));
5040 MockLayeredPool mock_layered_pool2(pool_.get(), TestGroupId("bar"));
5041 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
5042 IsOk());
5043 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
5044 .WillRepeatedly(Invoke(&mock_layered_pool2,
5045 &MockLayeredPool::ReleaseOneConnection));
5046 ClientSocketHandle handle;
5047 TestCompletionCallback callback;
5048 EXPECT_EQ(
5049 ERR_IO_PENDING,
5050 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
5051 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5052 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5053 pool_.get(), NetLogWithSource()));
5054 EXPECT_THAT(callback.WaitForResult(), IsOk());
5055 }
5056
5057 // Test that when a socket pool and group are at their limits, a request
5058 // with RespectLimits::DISABLED triggers creation of a new socket, and gets the
5059 // socket instead of a request with the same priority that was issued earlier,
5060 // but has RespectLimits::ENABLED.
TEST_F(ClientSocketPoolBaseTest,IgnoreLimits)5061 TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
5062 CreatePool(1, 1);
5063
5064 // Issue a request to reach the socket pool limit.
5065 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
5066 TestGroupId("a"), MAXIMUM_PRIORITY,
5067 ClientSocketPool::RespectLimits::ENABLED));
5068 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5069
5070 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5071
5072 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
5073 TestGroupId("a"), MAXIMUM_PRIORITY,
5074 ClientSocketPool::RespectLimits::ENABLED));
5075 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5076
5077 // Issue a request that ignores the limits, so a new ConnectJob is
5078 // created.
5079 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
5080 TestGroupId("a"), MAXIMUM_PRIORITY,
5081 ClientSocketPool::RespectLimits::DISABLED));
5082 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5083
5084 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
5085 EXPECT_FALSE(request(1)->have_result());
5086 }
5087
5088 // Test that when a socket pool and group are at their limits, a ConnectJob
5089 // issued for a request with RespectLimits::DISABLED is not cancelled when a
5090 // request with RespectLimits::ENABLED issued to the same group is cancelled.
TEST_F(ClientSocketPoolBaseTest,IgnoreLimitsCancelOtherJob)5091 TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
5092 CreatePool(1, 1);
5093
5094 // Issue a request to reach the socket pool limit.
5095 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
5096 TestGroupId("a"), MAXIMUM_PRIORITY,
5097 ClientSocketPool::RespectLimits::ENABLED));
5098 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5099
5100 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5101
5102 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
5103 TestGroupId("a"), MAXIMUM_PRIORITY,
5104 ClientSocketPool::RespectLimits::ENABLED));
5105 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5106
5107 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
5108 // created.
5109 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
5110 TestGroupId("a"), MAXIMUM_PRIORITY,
5111 ClientSocketPool::RespectLimits::DISABLED));
5112 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5113
5114 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
5115 // should not be cancelled.
5116 request(1)->handle()->Reset();
5117 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5118
5119 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
5120 EXPECT_FALSE(request(1)->have_result());
5121 }
5122
TEST_F(ClientSocketPoolBaseTest,ProxyAuthNoAuthCallback)5123 TEST_F(ClientSocketPoolBaseTest, ProxyAuthNoAuthCallback) {
5124 CreatePool(1, 1);
5125
5126 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5127
5128 ClientSocketHandle handle;
5129 TestCompletionCallback callback;
5130 EXPECT_EQ(
5131 ERR_IO_PENDING,
5132 handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY,
5133 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5134 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5135 pool_.get(), NetLogWithSource()));
5136
5137 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5138
5139 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
5140 EXPECT_FALSE(handle.is_initialized());
5141 EXPECT_FALSE(handle.socket());
5142
5143 // The group should now be empty, and thus be deleted.
5144 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5145 }
5146
5147 class TestAuthHelper {
5148 public:
5149 TestAuthHelper() = default;
5150 ~TestAuthHelper() = default;
5151
InitHandle(scoped_refptr<ClientSocketPool::SocketParams> params,TransportClientSocketPool * pool,RequestPriority priority=DEFAULT_PRIORITY,ClientSocketPool::RespectLimits respect_limits=ClientSocketPool::RespectLimits::ENABLED,const ClientSocketPool::GroupId & group_id_in=TestGroupId ("a"))5152 void InitHandle(
5153 scoped_refptr<ClientSocketPool::SocketParams> params,
5154 TransportClientSocketPool* pool,
5155 RequestPriority priority = DEFAULT_PRIORITY,
5156 ClientSocketPool::RespectLimits respect_limits =
5157 ClientSocketPool::RespectLimits::ENABLED,
5158 const ClientSocketPool::GroupId& group_id_in = TestGroupId("a")) {
5159 EXPECT_EQ(ERR_IO_PENDING,
5160 handle_.Init(group_id_in, params, base::nullopt, priority,
5161 SocketTag(), respect_limits, callback_.callback(),
5162 base::BindRepeating(&TestAuthHelper::AuthCallback,
5163 base::Unretained(this)),
5164 pool, NetLogWithSource()));
5165 }
5166
WaitForAuth()5167 void WaitForAuth() {
5168 run_loop_ = std::make_unique<base::RunLoop>();
5169 run_loop_->Run();
5170 run_loop_.reset();
5171 }
5172
WaitForAuthAndRestartSync()5173 void WaitForAuthAndRestartSync() {
5174 restart_sync_ = true;
5175 WaitForAuth();
5176 restart_sync_ = false;
5177 }
5178
WaitForAuthAndResetHandleSync()5179 void WaitForAuthAndResetHandleSync() {
5180 reset_handle_sync_ = true;
5181 WaitForAuth();
5182 reset_handle_sync_ = false;
5183 }
5184
RestartWithAuth()5185 void RestartWithAuth() {
5186 DCHECK(restart_with_auth_callback_);
5187 std::move(restart_with_auth_callback_).Run();
5188 }
5189
WaitForResult()5190 int WaitForResult() {
5191 int result = callback_.WaitForResult();
5192 // There shouldn't be any callback waiting to be invoked once the request is
5193 // complete.
5194 EXPECT_FALSE(restart_with_auth_callback_);
5195 // The socket should only be initialized on success.
5196 EXPECT_EQ(result == OK, handle_.is_initialized());
5197 EXPECT_EQ(result == OK, handle_.socket() != nullptr);
5198 return result;
5199 }
5200
handle()5201 ClientSocketHandle* handle() { return &handle_; }
auth_count() const5202 int auth_count() const { return auth_count_; }
have_result() const5203 int have_result() const { return callback_.have_result(); }
5204
5205 private:
AuthCallback(const HttpResponseInfo & response,HttpAuthController * auth_controller,base::OnceClosure restart_with_auth_callback)5206 void AuthCallback(const HttpResponseInfo& response,
5207 HttpAuthController* auth_controller,
5208 base::OnceClosure restart_with_auth_callback) {
5209 EXPECT_FALSE(restart_with_auth_callback_);
5210 EXPECT_TRUE(restart_with_auth_callback);
5211
5212 // Once there's a result, this method shouldn't be invoked again.
5213 EXPECT_FALSE(callback_.have_result());
5214
5215 ++auth_count_;
5216 run_loop_->Quit();
5217 if (restart_sync_) {
5218 std::move(restart_with_auth_callback).Run();
5219 return;
5220 }
5221
5222 restart_with_auth_callback_ = std::move(restart_with_auth_callback);
5223
5224 if (reset_handle_sync_) {
5225 handle_.Reset();
5226 return;
5227 }
5228 }
5229
5230 std::unique_ptr<base::RunLoop> run_loop_;
5231 base::OnceClosure restart_with_auth_callback_;
5232
5233 bool restart_sync_ = false;
5234 bool reset_handle_sync_ = false;
5235
5236 ClientSocketHandle handle_;
5237 int auth_count_ = 0;
5238 TestCompletionCallback callback_;
5239
5240 DISALLOW_COPY_AND_ASSIGN(TestAuthHelper);
5241 };
5242
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnce)5243 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnce) {
5244 CreatePool(1, 1);
5245 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5246
5247 TestAuthHelper auth_helper;
5248 auth_helper.InitHandle(params_, pool_.get());
5249 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5250 EXPECT_EQ(LOAD_STATE_CONNECTING,
5251 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5252
5253 auth_helper.WaitForAuth();
5254 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5255 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5256 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5257
5258 auth_helper.RestartWithAuth();
5259 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5260 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5261 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5262
5263 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5264 EXPECT_EQ(1, auth_helper.auth_count());
5265 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5266 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5267 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5268 EXPECT_EQ(0, pool_->IdleSocketCount());
5269 }
5270
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceSync)5271 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSync) {
5272 CreatePool(1, 1);
5273 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5274
5275 TestAuthHelper auth_helper;
5276 auth_helper.InitHandle(params_, pool_.get());
5277 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5278 EXPECT_EQ(LOAD_STATE_CONNECTING,
5279 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5280
5281 auth_helper.WaitForAuthAndRestartSync();
5282 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5283 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5284 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5285
5286 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5287 EXPECT_EQ(1, auth_helper.auth_count());
5288 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5289 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5290 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5291 EXPECT_EQ(0, pool_->IdleSocketCount());
5292 }
5293
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceFails)5294 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFails) {
5295 CreatePool(1, 1);
5296 connect_job_factory_->set_job_type(
5297 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5298
5299 TestAuthHelper auth_helper;
5300 auth_helper.InitHandle(params_, pool_.get());
5301 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5302
5303 auth_helper.WaitForAuth();
5304 auth_helper.RestartWithAuth();
5305 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5306
5307 EXPECT_EQ(1, auth_helper.auth_count());
5308 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5309 EXPECT_EQ(0, pool_->IdleSocketCount());
5310 }
5311
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceSyncFails)5312 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSyncFails) {
5313 CreatePool(1, 1);
5314 connect_job_factory_->set_job_type(
5315 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5316
5317 TestAuthHelper auth_helper;
5318 auth_helper.InitHandle(params_, pool_.get());
5319 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5320
5321 auth_helper.WaitForAuthAndRestartSync();
5322 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5323
5324 EXPECT_EQ(1, auth_helper.auth_count());
5325 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5326 EXPECT_EQ(0, pool_->IdleSocketCount());
5327 }
5328
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceDeleteHandle)5329 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandle) {
5330 CreatePool(1, 1);
5331 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5332
5333 TestAuthHelper auth_helper;
5334 auth_helper.InitHandle(params_, pool_.get());
5335 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5336
5337 auth_helper.WaitForAuth();
5338 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5339
5340 auth_helper.handle()->Reset();
5341
5342 EXPECT_EQ(1, auth_helper.auth_count());
5343 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5344 EXPECT_EQ(0, pool_->IdleSocketCount());
5345 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5346 EXPECT_FALSE(auth_helper.handle()->socket());
5347 }
5348
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceDeleteHandleSync)5349 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandleSync) {
5350 CreatePool(1, 1);
5351 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5352
5353 TestAuthHelper auth_helper;
5354 auth_helper.InitHandle(params_, pool_.get());
5355 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5356
5357 auth_helper.WaitForAuthAndResetHandleSync();
5358 EXPECT_EQ(1, auth_helper.auth_count());
5359 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5360 EXPECT_EQ(0, pool_->IdleSocketCount());
5361 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5362 EXPECT_FALSE(auth_helper.handle()->socket());
5363 }
5364
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceFlushWithError)5365 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFlushWithError) {
5366 CreatePool(1, 1);
5367 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5368
5369 TestAuthHelper auth_helper;
5370 auth_helper.InitHandle(params_, pool_.get());
5371 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5372
5373 auth_helper.WaitForAuth();
5374
5375 pool_->FlushWithError(ERR_FAILED, "Network changed");
5376 base::RunLoop().RunUntilIdle();
5377
5378 // When flushing the socket pool, bound sockets should delay returning the
5379 // error until completion.
5380 EXPECT_FALSE(auth_helper.have_result());
5381 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5382 EXPECT_EQ(0, pool_->IdleSocketCount());
5383
5384 auth_helper.RestartWithAuth();
5385 // The callback should be called asynchronously.
5386 EXPECT_FALSE(auth_helper.have_result());
5387
5388 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_FAILED));
5389 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5390 EXPECT_EQ(0, pool_->IdleSocketCount());
5391 }
5392
TEST_F(ClientSocketPoolBaseTest,ProxyAuthTwice)5393 TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwice) {
5394 CreatePool(1, 1);
5395 connect_job_factory_->set_job_type(
5396 TestConnectJob::kMockAuthChallengeTwiceJob);
5397
5398 TestAuthHelper auth_helper;
5399 auth_helper.InitHandle(params_, pool_.get());
5400 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5401 EXPECT_EQ(LOAD_STATE_CONNECTING,
5402 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5403
5404 auth_helper.WaitForAuth();
5405 auth_helper.RestartWithAuth();
5406 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5407 EXPECT_EQ(1, auth_helper.auth_count());
5408 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5409 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5410
5411 auth_helper.WaitForAuth();
5412 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5413 EXPECT_EQ(2, auth_helper.auth_count());
5414 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5415 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5416
5417 auth_helper.RestartWithAuth();
5418 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5419 EXPECT_EQ(2, auth_helper.auth_count());
5420 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5421 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5422
5423 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5424 EXPECT_EQ(2, auth_helper.auth_count());
5425 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5426 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5427 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5428 EXPECT_EQ(0, pool_->IdleSocketCount());
5429 }
5430
TEST_F(ClientSocketPoolBaseTest,ProxyAuthTwiceFails)5431 TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwiceFails) {
5432 CreatePool(1, 1);
5433 connect_job_factory_->set_job_type(
5434 TestConnectJob::kMockAuthChallengeTwiceFailingJob);
5435
5436 TestAuthHelper auth_helper;
5437 auth_helper.InitHandle(params_, pool_.get());
5438 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5439
5440 auth_helper.WaitForAuth();
5441 auth_helper.RestartWithAuth();
5442 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5443 EXPECT_EQ(1, auth_helper.auth_count());
5444
5445 auth_helper.WaitForAuth();
5446 auth_helper.RestartWithAuth();
5447 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5448 EXPECT_EQ(2, auth_helper.auth_count());
5449
5450 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5451 EXPECT_EQ(2, auth_helper.auth_count());
5452 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5453 EXPECT_EQ(0, pool_->IdleSocketCount());
5454 }
5455
5456 // Makes sure that when a bound request is destroyed, a new ConnectJob is
5457 // created, if needed.
TEST_F(ClientSocketPoolBaseTest,ProxyAuthCreateNewConnectJobOnDestroyBoundRequest)5458 TEST_F(ClientSocketPoolBaseTest,
5459 ProxyAuthCreateNewConnectJobOnDestroyBoundRequest) {
5460 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5461 connect_job_factory_->set_job_type(
5462 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5463
5464 // First request creates a ConnectJob.
5465 TestAuthHelper auth_helper1;
5466 auth_helper1.InitHandle(params_, pool_.get());
5467 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5468
5469 // A second request come in, but no new ConnectJob is needed, since the limit
5470 // has been reached.
5471 TestAuthHelper auth_helper2;
5472 auth_helper2.InitHandle(params_, pool_.get());
5473 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5474
5475 // Run until the auth callback for the first request is invoked.
5476 auth_helper1.WaitForAuth();
5477 EXPECT_EQ(0, auth_helper2.auth_count());
5478 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5479 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5480 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5481
5482 // Make connect jobs succeed, then cancel the first request, which should
5483 // destroy the bound ConnectJob, and cause a new ConnectJob to start.
5484 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5485 auth_helper1.handle()->Reset();
5486 EXPECT_EQ(0, auth_helper2.auth_count());
5487 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5488
5489 // The second ConnectJob should succeed.
5490 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5491 EXPECT_EQ(0, auth_helper2.auth_count());
5492 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5493 }
5494
5495 // Makes sure that when a bound request is destroyed, a new ConnectJob is
5496 // created for another group, if needed.
TEST_F(ClientSocketPoolBaseTest,ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups)5497 TEST_F(ClientSocketPoolBaseTest,
5498 ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups) {
5499 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5500 connect_job_factory_->set_job_type(
5501 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5502
5503 // First request creates a ConnectJob.
5504 TestAuthHelper auth_helper1;
5505 auth_helper1.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY);
5506 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5507
5508 // A second request come in, but no new ConnectJob is needed, since the limit
5509 // has been reached.
5510 TestAuthHelper auth_helper2;
5511 auth_helper2.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
5512 ClientSocketPool::RespectLimits::ENABLED,
5513 TestGroupId("b"));
5514 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5515 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5516
5517 // Run until the auth callback for the first request is invoked.
5518 auth_helper1.WaitForAuth();
5519 EXPECT_EQ(0, auth_helper2.auth_count());
5520 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5521 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5522 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5523 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5524 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
5525 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
5526
5527 // Make connect jobs succeed, then cancel the first request, which should
5528 // destroy the bound ConnectJob, and cause a new ConnectJob to start for the
5529 // other group.
5530 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5531 auth_helper1.handle()->Reset();
5532 EXPECT_EQ(0, auth_helper2.auth_count());
5533 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5534 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5535
5536 // The second ConnectJob should succeed.
5537 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5538 EXPECT_EQ(0, auth_helper2.auth_count());
5539 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5540 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5541 }
5542
5543 // Test that once an auth challenge is bound, that's the request that gets all
5544 // subsequent calls and the socket itself.
TEST_F(ClientSocketPoolBaseTest,ProxyAuthStaysBound)5545 TEST_F(ClientSocketPoolBaseTest, ProxyAuthStaysBound) {
5546 CreatePool(1, 1);
5547 connect_job_factory_->set_job_type(
5548 TestConnectJob::kMockAuthChallengeTwiceJob);
5549
5550 // First request creates a ConnectJob.
5551 TestAuthHelper auth_helper1;
5552 auth_helper1.InitHandle(params_, pool_.get(), LOWEST);
5553 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5554
5555 // A second, higher priority request is made.
5556 TestAuthHelper auth_helper2;
5557 auth_helper2.InitHandle(params_, pool_.get(), LOW);
5558 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5559
5560 // Run until the auth callback for the second request is invoked.
5561 auth_helper2.WaitForAuth();
5562 EXPECT_EQ(0, auth_helper1.auth_count());
5563 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5564 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5565 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5566
5567 // Start a higher priority job. It shouldn't be able to steal |auth_helper2|'s
5568 // ConnectJob.
5569 TestAuthHelper auth_helper3;
5570 auth_helper3.InitHandle(params_, pool_.get(), HIGHEST);
5571 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5572
5573 // Start a higher job that ignores limits, creating a hanging socket. It
5574 // shouldn't be able to steal |auth_helper2|'s ConnectJob.
5575 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5576 TestAuthHelper auth_helper4;
5577 auth_helper4.InitHandle(params_, pool_.get(), HIGHEST,
5578 ClientSocketPool::RespectLimits::DISABLED);
5579 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5580
5581 // Restart with auth, and |auth_helper2|'s auth method should be invoked
5582 // again.
5583 auth_helper2.RestartWithAuth();
5584 auth_helper2.WaitForAuth();
5585 EXPECT_EQ(0, auth_helper1.auth_count());
5586 EXPECT_FALSE(auth_helper1.have_result());
5587 EXPECT_EQ(2, auth_helper2.auth_count());
5588 EXPECT_FALSE(auth_helper2.have_result());
5589 EXPECT_EQ(0, auth_helper3.auth_count());
5590 EXPECT_FALSE(auth_helper3.have_result());
5591 EXPECT_EQ(0, auth_helper4.auth_count());
5592 EXPECT_FALSE(auth_helper4.have_result());
5593
5594 // Advance auth again, and |auth_helper2| should get the socket.
5595 auth_helper2.RestartWithAuth();
5596 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5597 // The hung ConnectJob for the RespectLimits::DISABLED request is still in the
5598 // socket pool.
5599 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5600 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5601 EXPECT_EQ(0, auth_helper1.auth_count());
5602 EXPECT_FALSE(auth_helper1.have_result());
5603 EXPECT_EQ(0, auth_helper3.auth_count());
5604 EXPECT_FALSE(auth_helper3.have_result());
5605 EXPECT_EQ(0, auth_helper4.auth_count());
5606 EXPECT_FALSE(auth_helper4.have_result());
5607
5608 // If the socket is returned to the socket pool, the RespectLimits::DISABLED
5609 // socket request should be able to claim it.
5610 auth_helper2.handle()->Reset();
5611 EXPECT_THAT(auth_helper4.WaitForResult(), IsOk());
5612 EXPECT_EQ(0, auth_helper1.auth_count());
5613 EXPECT_FALSE(auth_helper1.have_result());
5614 EXPECT_EQ(0, auth_helper3.auth_count());
5615 EXPECT_FALSE(auth_helper3.have_result());
5616 EXPECT_EQ(0, auth_helper4.auth_count());
5617 }
5618
5619 enum class RefreshType {
5620 kServer,
5621 kProxy,
5622 };
5623
5624 // Common base class to test RefreshGroup() when called from either
5625 // OnSSLConfigForServerChanged() matching a specific group or the pool's proxy.
5626 //
5627 // Tests which test behavior specific to one or the other case should use
5628 // ClientSocketPoolBaseTest directly. In particular, there is no "other group"
5629 // when the pool's proxy matches.
5630 class ClientSocketPoolBaseRefreshTest
5631 : public ClientSocketPoolBaseTest,
5632 public testing::WithParamInterface<RefreshType> {
5633 public:
CreatePoolForRefresh(int max_sockets,int max_sockets_per_group,bool enable_backup_connect_jobs=false)5634 void CreatePoolForRefresh(int max_sockets,
5635 int max_sockets_per_group,
5636 bool enable_backup_connect_jobs = false) {
5637 switch (GetParam()) {
5638 case RefreshType::kServer:
5639 CreatePool(max_sockets, max_sockets_per_group,
5640 enable_backup_connect_jobs);
5641 break;
5642 case RefreshType::kProxy:
5643 CreatePoolWithIdleTimeouts(
5644 max_sockets, max_sockets_per_group, kUnusedIdleSocketTimeout,
5645 ClientSocketPool::used_idle_socket_timeout(),
5646 enable_backup_connect_jobs,
5647 ProxyServer::FromPacString("HTTPS myproxy:70"));
5648 break;
5649 }
5650 }
5651
GetGroupId()5652 static ClientSocketPool::GroupId GetGroupId() {
5653 return TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5654 }
5655
GetGroupIdInPartition()5656 static ClientSocketPool::GroupId GetGroupIdInPartition() {
5657 // Note this GroupId will match GetGroupId() unless
5658 // kPartitionConnectionsByNetworkIsolationKey is enabled.
5659 const auto kOrigin = url::Origin::Create(GURL("https://b/"));
5660 const NetworkIsolationKey kNetworkIsolationKey(kOrigin, kOrigin);
5661 return TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl,
5662 PrivacyMode::PRIVACY_MODE_DISABLED,
5663 kNetworkIsolationKey);
5664 }
5665
OnSSLConfigForServerChanged()5666 void OnSSLConfigForServerChanged() {
5667 switch (GetParam()) {
5668 case RefreshType::kServer:
5669 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
5670 break;
5671 case RefreshType::kProxy:
5672 pool_->OnSSLConfigForServerChanged(HostPortPair("myproxy", 70));
5673 break;
5674 }
5675 }
5676 };
5677
5678 INSTANTIATE_TEST_SUITE_P(RefreshType,
5679 ClientSocketPoolBaseRefreshTest,
5680 ::testing::Values(RefreshType::kServer,
5681 RefreshType::kProxy));
5682
TEST_P(ClientSocketPoolBaseRefreshTest,RefreshGroupCreatesNewConnectJobs)5683 TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupCreatesNewConnectJobs) {
5684 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5685 const ClientSocketPool::GroupId kGroupId = GetGroupId();
5686
5687 // First job will be waiting until it gets aborted.
5688 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5689
5690 ClientSocketHandle handle;
5691 TestCompletionCallback callback;
5692 EXPECT_THAT(
5693 handle.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5694 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5695 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5696 pool_.get(), NetLogWithSource()),
5697 IsError(ERR_IO_PENDING));
5698
5699 // Switch connect job types, so creating a new ConnectJob will result in
5700 // success.
5701 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
5702
5703 OnSSLConfigForServerChanged();
5704 EXPECT_EQ(OK, callback.WaitForResult());
5705 ASSERT_TRUE(handle.socket());
5706 EXPECT_EQ(0, pool_->IdleSocketCount());
5707 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5708 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(kGroupId));
5709 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5710 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5711 }
5712
TEST_P(ClientSocketPoolBaseRefreshTest,RefreshGroupClosesIdleConnectJobs)5713 TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupClosesIdleConnectJobs) {
5714 base::test::ScopedFeatureList feature_list;
5715 feature_list.InitAndEnableFeature(
5716 features::kPartitionConnectionsByNetworkIsolationKey);
5717
5718 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5719 const ClientSocketPool::GroupId kGroupId = GetGroupId();
5720 const ClientSocketPool::GroupId kGroupIdInPartition = GetGroupIdInPartition();
5721
5722 pool_->RequestSockets(kGroupId, params_, base::nullopt, 2,
5723 NetLogWithSource());
5724 pool_->RequestSockets(kGroupIdInPartition, params_, base::nullopt, 2,
5725 NetLogWithSource());
5726 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5727 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdInPartition));
5728 EXPECT_EQ(4, pool_->IdleSocketCount());
5729 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupId));
5730 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupIdInPartition));
5731
5732 OnSSLConfigForServerChanged();
5733 EXPECT_EQ(0, pool_->IdleSocketCount());
5734 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5735 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdInPartition));
5736 }
5737
TEST_F(ClientSocketPoolBaseTest,RefreshGroupDoesNotCloseIdleConnectJobsInOtherGroup)5738 TEST_F(ClientSocketPoolBaseTest,
5739 RefreshGroupDoesNotCloseIdleConnectJobsInOtherGroup) {
5740 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5741 const ClientSocketPool::GroupId kGroupId =
5742 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5743 const ClientSocketPool::GroupId kOtherGroupId =
5744 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
5745
5746 pool_->RequestSockets(kOtherGroupId, params_, base::nullopt, 2,
5747 NetLogWithSource());
5748 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5749 EXPECT_EQ(2, pool_->IdleSocketCount());
5750 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5751
5752 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
5753 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5754 EXPECT_EQ(2, pool_->IdleSocketCount());
5755 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5756 }
5757
TEST_P(ClientSocketPoolBaseRefreshTest,RefreshGroupPreventsSocketReuse)5758 TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupPreventsSocketReuse) {
5759 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5760 const ClientSocketPool::GroupId kGroupId = GetGroupId();
5761
5762 ClientSocketHandle handle;
5763 TestCompletionCallback callback;
5764 EXPECT_THAT(
5765 handle.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5766 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5767 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5768 pool_.get(), NetLogWithSource()),
5769 IsOk());
5770 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5771 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5772
5773 OnSSLConfigForServerChanged();
5774
5775 handle.Reset();
5776 EXPECT_EQ(0, pool_->IdleSocketCount());
5777 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5778 }
5779
TEST_F(ClientSocketPoolBaseTest,RefreshGroupDoesNotPreventSocketReuseInOtherGroup)5780 TEST_F(ClientSocketPoolBaseTest,
5781 RefreshGroupDoesNotPreventSocketReuseInOtherGroup) {
5782 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5783 const ClientSocketPool::GroupId kGroupId =
5784 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5785 const ClientSocketPool::GroupId kOtherGroupId =
5786 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
5787
5788 ClientSocketHandle handle;
5789 TestCompletionCallback callback;
5790 EXPECT_THAT(
5791 handle.Init(kOtherGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5792 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5793 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5794 pool_.get(), NetLogWithSource()),
5795 IsOk());
5796 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5797 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5798
5799 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
5800
5801 handle.Reset();
5802 EXPECT_EQ(1, pool_->IdleSocketCount());
5803 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5804 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5805 }
5806
TEST_P(ClientSocketPoolBaseRefreshTest,RefreshGroupReplacesBoundConnectJobOnConnect)5807 TEST_P(ClientSocketPoolBaseRefreshTest,
5808 RefreshGroupReplacesBoundConnectJobOnConnect) {
5809 CreatePoolForRefresh(1, 1);
5810 const ClientSocketPool::GroupId kGroupId = GetGroupId();
5811 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5812
5813 TestAuthHelper auth_helper;
5814 auth_helper.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
5815 ClientSocketPool::RespectLimits::ENABLED, kGroupId);
5816 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5817
5818 auth_helper.WaitForAuth();
5819
5820 // This should update the generation, but not cancel the old ConnectJob - it's
5821 // not safe to do anything while waiting on the original ConnectJob.
5822 OnSSLConfigForServerChanged();
5823
5824 // Providing auth credentials and restarting the request with them will cause
5825 // the ConnectJob to complete successfully, but the result will be discarded
5826 // because of the generation mismatch.
5827 auth_helper.RestartWithAuth();
5828
5829 // Despite using ConnectJobs that simulate a single challenge, a second
5830 // challenge will be seen, due to using a new ConnectJob.
5831 auth_helper.WaitForAuth();
5832 auth_helper.RestartWithAuth();
5833
5834 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5835 EXPECT_TRUE(auth_helper.handle()->socket());
5836 EXPECT_EQ(2, auth_helper.auth_count());
5837
5838 // When released, the socket will be returned to the socket pool, and
5839 // available for reuse.
5840 auth_helper.handle()->Reset();
5841 EXPECT_EQ(1, pool_->IdleSocketCount());
5842 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5843 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId));
5844 }
5845
TEST_F(ClientSocketPoolBaseTest,RefreshProxyRefreshesAllGroups)5846 TEST_F(ClientSocketPoolBaseTest, RefreshProxyRefreshesAllGroups) {
5847 CreatePoolWithIdleTimeouts(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
5848 kUnusedIdleSocketTimeout,
5849 ClientSocketPool::used_idle_socket_timeout(),
5850 false /* no backup connect jobs */,
5851 ProxyServer::FromPacString("HTTPS myproxy:70"));
5852
5853 const ClientSocketPool::GroupId kGroupId1 =
5854 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl);
5855 const ClientSocketPool::GroupId kGroupId2 =
5856 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
5857 const ClientSocketPool::GroupId kGroupId3 =
5858 TestGroupId("c", 443, ClientSocketPool::SocketType::kSsl);
5859
5860 // Make three sockets in three different groups. The third socket is released
5861 // to the pool as idle.
5862 ClientSocketHandle handle1, handle2, handle3;
5863 TestCompletionCallback callback;
5864 EXPECT_THAT(
5865 handle1.Init(kGroupId1, params_, base::nullopt, DEFAULT_PRIORITY,
5866 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5867 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5868 pool_.get(), NetLogWithSource()),
5869 IsOk());
5870 EXPECT_THAT(
5871 handle2.Init(kGroupId2, params_, base::nullopt, DEFAULT_PRIORITY,
5872 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5873 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5874 pool_.get(), NetLogWithSource()),
5875 IsOk());
5876 EXPECT_THAT(
5877 handle3.Init(kGroupId3, params_, base::nullopt, DEFAULT_PRIORITY,
5878 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5879 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5880 pool_.get(), NetLogWithSource()),
5881 IsOk());
5882 handle3.Reset();
5883 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5884 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5885 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5886 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2));
5887 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3));
5888 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3));
5889
5890 // Changes to some other proxy do not affect the pool. The idle socket remains
5891 // alive and closing |handle2| makes the socket available for the pool.
5892 pool_->OnSSLConfigForServerChanged(HostPortPair("someotherproxy", 70));
5893
5894 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5895 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5896 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5897 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2));
5898 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3));
5899 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3));
5900
5901 handle2.Reset();
5902 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5903 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId2));
5904
5905 // Changes to the matching proxy refreshes all groups.
5906 pool_->OnSSLConfigForServerChanged(HostPortPair("myproxy", 70));
5907
5908 // Idle sockets are closed.
5909 EXPECT_EQ(0, pool_->IdleSocketCount());
5910 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId2));
5911 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId3));
5912
5913 // The active socket, however, continues to be active.
5914 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5915 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5916
5917 // Closing it does not make it available for the pool.
5918 handle1.Reset();
5919 EXPECT_EQ(0, pool_->IdleSocketCount());
5920 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId1));
5921 }
5922
TEST_F(ClientSocketPoolBaseTest,RefreshBothPrivacyAndNormalSockets)5923 TEST_F(ClientSocketPoolBaseTest, RefreshBothPrivacyAndNormalSockets) {
5924 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5925
5926 const ClientSocketPool::GroupId kGroupId =
5927 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl,
5928 PrivacyMode::PRIVACY_MODE_DISABLED);
5929 const ClientSocketPool::GroupId kGroupIdPrivacy =
5930 TestGroupId("a", 443, ClientSocketPool::SocketType::kSsl,
5931 PrivacyMode::PRIVACY_MODE_ENABLED);
5932 const ClientSocketPool::GroupId kOtherGroupId =
5933 TestGroupId("b", 443, ClientSocketPool::SocketType::kSsl);
5934
5935 // Make a socket in each groups.
5936 ClientSocketHandle handle1, handle2, handle3;
5937 TestCompletionCallback callback;
5938 EXPECT_THAT(
5939 handle1.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5940 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5941 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5942 pool_.get(), NetLogWithSource()),
5943 IsOk());
5944 EXPECT_THAT(
5945 handle2.Init(kGroupIdPrivacy, params_, base::nullopt, DEFAULT_PRIORITY,
5946 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5947 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5948 pool_.get(), NetLogWithSource()),
5949 IsOk());
5950 EXPECT_THAT(
5951 handle3.Init(kOtherGroupId, params_, base::nullopt, DEFAULT_PRIORITY,
5952 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5953 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5954 pool_.get(), NetLogWithSource()),
5955 IsOk());
5956 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5957 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5958 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy));
5959 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy));
5960 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5961 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5962
5963 pool_->OnSSLConfigForServerChanged(HostPortPair("a", 443));
5964
5965 // Active sockets continue to be active.
5966 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5967 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5968 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy));
5969 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy));
5970 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5971 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5972
5973 // Closing them leaves kOtherGroupId alone, but kGroupId and kGroupIdPrivacy
5974 // are unusable.
5975 handle1.Reset();
5976 handle2.Reset();
5977 handle3.Reset();
5978 EXPECT_EQ(1, pool_->IdleSocketCount());
5979 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5980 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdPrivacy));
5981 EXPECT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5982 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5983 }
5984
5985 } // namespace
5986
5987 } // namespace net
5988