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