xref: /aosp_15_r20/external/cronet/net/socket/tcp_client_socket_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 // This file contains some tests for TCPClientSocket.
6 // transport_client_socket_unittest.cc contans some other tests that
7 // are common for TCP and other types of sockets.
8 
9 #include "net/socket/tcp_client_socket.h"
10 
11 #include <stddef.h>
12 
13 #include <set>
14 #include <string>
15 #include <vector>
16 
17 #include "base/strings/string_number_conversions.h"
18 #include "base/test/bind.h"
19 #include "base/test/power_monitor_test.h"
20 #include "base/test/scoped_feature_list.h"
21 #include "base/test/task_environment.h"
22 #include "build/build_config.h"
23 #include "net/base/features.h"
24 #include "net/base/ip_address.h"
25 #include "net/base/ip_endpoint.h"
26 #include "net/base/net_errors.h"
27 #include "net/base/test_completion_callback.h"
28 #include "net/log/net_log_source.h"
29 #include "net/nqe/network_quality_estimator_test_util.h"
30 #include "net/socket/socket_performance_watcher.h"
31 #include "net/socket/socket_test_util.h"
32 #include "net/socket/tcp_server_socket.h"
33 #include "net/test/embedded_test_server/embedded_test_server.h"
34 #include "net/test/gtest_util.h"
35 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
36 #include "testing/gmock/include/gmock/gmock.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38 
39 // This matches logic in tcp_client_socket.cc. Only used once, but defining it
40 // in this file instead of just inlining the OS checks where its used makes it
41 // more grep-able.
42 #if !BUILDFLAG(IS_ANDROID)
43 #define TCP_CLIENT_SOCKET_OBSERVES_SUSPEND
44 #endif
45 
46 using net::test::IsError;
47 using net::test::IsOk;
48 using testing::Not;
49 
50 namespace base {
51 class TimeDelta;
52 }
53 
54 namespace net {
55 
56 namespace {
57 
58 class TCPClientSocketTest : public testing::Test {
59  public:
TCPClientSocketTest()60   TCPClientSocketTest()
61       : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}
62 
~TCPClientSocketTest()63   ~TCPClientSocketTest() override { base::PowerMonitor::ShutdownForTesting(); }
64 
Suspend()65   void Suspend() { power_monitor_source_.Suspend(); }
Resume()66   void Resume() { power_monitor_source_.Resume(); }
67 
CreateConnectedSockets(std::unique_ptr<StreamSocket> * accepted_socket,std::unique_ptr<TCPClientSocket> * client_socket,std::unique_ptr<ServerSocket> * server_socket_opt=nullptr)68   void CreateConnectedSockets(
69       std::unique_ptr<StreamSocket>* accepted_socket,
70       std::unique_ptr<TCPClientSocket>* client_socket,
71       std::unique_ptr<ServerSocket>* server_socket_opt = nullptr) {
72     IPAddress local_address = IPAddress::IPv4Localhost();
73 
74     std::unique_ptr<TCPServerSocket> server_socket =
75         std::make_unique<TCPServerSocket>(nullptr, NetLogSource());
76     ASSERT_THAT(server_socket->Listen(IPEndPoint(local_address, 0), 1,
77                                       /*ipv6_only=*/std::nullopt),
78                 IsOk());
79     IPEndPoint server_address;
80     ASSERT_THAT(server_socket->GetLocalAddress(&server_address), IsOk());
81 
82     *client_socket = std::make_unique<TCPClientSocket>(
83         AddressList(server_address), nullptr, nullptr, nullptr, NetLogSource());
84 
85     EXPECT_THAT((*client_socket)->Bind(IPEndPoint(local_address, 0)), IsOk());
86 
87     IPEndPoint local_address_result;
88     EXPECT_THAT((*client_socket)->GetLocalAddress(&local_address_result),
89                 IsOk());
90     EXPECT_EQ(local_address, local_address_result.address());
91 
92     TestCompletionCallback connect_callback;
93     int connect_result = (*client_socket)->Connect(connect_callback.callback());
94 
95     TestCompletionCallback accept_callback;
96     int result =
97         server_socket->Accept(accepted_socket, accept_callback.callback());
98     result = accept_callback.GetResult(result);
99     ASSERT_THAT(result, IsOk());
100 
101     ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
102 
103     EXPECT_TRUE((*client_socket)->IsConnected());
104     EXPECT_TRUE((*accepted_socket)->IsConnected());
105     if (server_socket_opt)
106       *server_socket_opt = std::move(server_socket);
107   }
108 
109  private:
110   base::test::TaskEnvironment task_environment_;
111   base::test::ScopedPowerMonitorTestSource power_monitor_source_;
112 };
113 
114 // Try binding a socket to loopback interface and verify that we can
115 // still connect to a server on the same interface.
TEST_F(TCPClientSocketTest,BindLoopbackToLoopback)116 TEST_F(TCPClientSocketTest, BindLoopbackToLoopback) {
117   IPAddress lo_address = IPAddress::IPv4Localhost();
118 
119   TCPServerSocket server(nullptr, NetLogSource());
120   ASSERT_THAT(server.Listen(IPEndPoint(lo_address, 0), 1,
121                             /*ipv6_only=*/std::nullopt),
122               IsOk());
123   IPEndPoint server_address;
124   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
125 
126   TCPClientSocket socket(AddressList(server_address), nullptr, nullptr, nullptr,
127                          NetLogSource());
128 
129   EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
130 
131   IPEndPoint local_address_result;
132   EXPECT_THAT(socket.GetLocalAddress(&local_address_result), IsOk());
133   EXPECT_EQ(lo_address, local_address_result.address());
134 
135   TestCompletionCallback connect_callback;
136   int connect_result = socket.Connect(connect_callback.callback());
137 
138   TestCompletionCallback accept_callback;
139   std::unique_ptr<StreamSocket> accepted_socket;
140   int result = server.Accept(&accepted_socket, accept_callback.callback());
141   result = accept_callback.GetResult(result);
142   ASSERT_THAT(result, IsOk());
143 
144   EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
145 
146   EXPECT_TRUE(socket.IsConnected());
147   socket.Disconnect();
148   EXPECT_FALSE(socket.IsConnected());
149   EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
150             socket.GetLocalAddress(&local_address_result));
151 }
152 
153 // Try to bind socket to the loopback interface and connect to an
154 // external address, verify that connection fails.
TEST_F(TCPClientSocketTest,BindLoopbackToExternal)155 TEST_F(TCPClientSocketTest, BindLoopbackToExternal) {
156   IPAddress external_ip(72, 14, 213, 105);
157   TCPClientSocket socket(AddressList::CreateFromIPAddress(external_ip, 80),
158                          nullptr, nullptr, nullptr, NetLogSource());
159 
160   EXPECT_THAT(socket.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)), IsOk());
161 
162   TestCompletionCallback connect_callback;
163   int result = socket.Connect(connect_callback.callback());
164 
165   // We may get different errors here on different system, but
166   // connect() is not expected to succeed.
167   EXPECT_THAT(connect_callback.GetResult(result), Not(IsOk()));
168 }
169 
170 // Bind a socket to the IPv4 loopback interface and try to connect to
171 // the IPv6 loopback interface, verify that connection fails.
TEST_F(TCPClientSocketTest,BindLoopbackToIPv6)172 TEST_F(TCPClientSocketTest, BindLoopbackToIPv6) {
173   TCPServerSocket server(nullptr, NetLogSource());
174   int listen_result =
175       server.Listen(IPEndPoint(IPAddress::IPv6Localhost(), 0), 1,
176                     /*ipv6_only=*/std::nullopt);
177   if (listen_result != OK) {
178     LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is disabled."
179                   " Skipping the test";
180     return;
181   }
182 
183   IPEndPoint server_address;
184   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
185   TCPClientSocket socket(AddressList(server_address), nullptr, nullptr, nullptr,
186                          NetLogSource());
187 
188   EXPECT_THAT(socket.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)), IsOk());
189 
190   TestCompletionCallback connect_callback;
191   int result = socket.Connect(connect_callback.callback());
192 
193   EXPECT_THAT(connect_callback.GetResult(result), Not(IsOk()));
194 }
195 
TEST_F(TCPClientSocketTest,WasEverUsed)196 TEST_F(TCPClientSocketTest, WasEverUsed) {
197   IPAddress lo_address = IPAddress::IPv4Localhost();
198   TCPServerSocket server(nullptr, NetLogSource());
199   ASSERT_THAT(
200       server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/std::nullopt),
201       IsOk());
202   IPEndPoint server_address;
203   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
204 
205   TCPClientSocket socket(AddressList(server_address), nullptr, nullptr, nullptr,
206                          NetLogSource());
207 
208   EXPECT_FALSE(socket.WasEverUsed());
209 
210   EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
211 
212   // Just connecting the socket should not set WasEverUsed.
213   TestCompletionCallback connect_callback;
214   int connect_result = socket.Connect(connect_callback.callback());
215   EXPECT_FALSE(socket.WasEverUsed());
216 
217   TestCompletionCallback accept_callback;
218   std::unique_ptr<StreamSocket> accepted_socket;
219   int result = server.Accept(&accepted_socket, accept_callback.callback());
220   ASSERT_THAT(accept_callback.GetResult(result), IsOk());
221   EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
222 
223   EXPECT_FALSE(socket.WasEverUsed());
224   EXPECT_TRUE(socket.IsConnected());
225 
226   // Writing some data to the socket _should_ set WasEverUsed.
227   const char kRequest[] = "GET / HTTP/1.0";
228   auto write_buffer = base::MakeRefCounted<StringIOBuffer>(kRequest);
229   TestCompletionCallback write_callback;
230   socket.Write(write_buffer.get(), write_buffer->size(),
231                write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
232   EXPECT_TRUE(socket.WasEverUsed());
233   socket.Disconnect();
234   EXPECT_FALSE(socket.IsConnected());
235 
236   EXPECT_TRUE(socket.WasEverUsed());
237 
238   // Re-use the socket, which should set WasEverUsed to false.
239   EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
240   TestCompletionCallback connect_callback2;
241   connect_result = socket.Connect(connect_callback2.callback());
242   EXPECT_FALSE(socket.WasEverUsed());
243 }
244 
245 // Tests that DNS aliases can be stored in a socket for reuse.
TEST_F(TCPClientSocketTest,DnsAliasesPersistForReuse)246 TEST_F(TCPClientSocketTest, DnsAliasesPersistForReuse) {
247   IPAddress lo_address = IPAddress::IPv4Localhost();
248   TCPServerSocket server(nullptr, NetLogSource());
249   ASSERT_THAT(
250       server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/std::nullopt),
251       IsOk());
252   IPEndPoint server_address;
253   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
254 
255   // Create a socket.
256   TCPClientSocket socket(AddressList(server_address), nullptr, nullptr, nullptr,
257                          NetLogSource());
258   EXPECT_FALSE(socket.WasEverUsed());
259   EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
260 
261   // The socket's DNS aliases are unset.
262   EXPECT_TRUE(socket.GetDnsAliases().empty());
263 
264   // Set the aliases.
265   std::set<std::string> dns_aliases({"alias1", "alias2", "host"});
266   socket.SetDnsAliases(dns_aliases);
267 
268   // Verify that the aliases are set.
269   EXPECT_THAT(socket.GetDnsAliases(),
270               testing::UnorderedElementsAre("alias1", "alias2", "host"));
271 
272   // Connect the socket.
273   TestCompletionCallback connect_callback;
274   int connect_result = socket.Connect(connect_callback.callback());
275   EXPECT_FALSE(socket.WasEverUsed());
276   TestCompletionCallback accept_callback;
277   std::unique_ptr<StreamSocket> accepted_socket;
278   int result = server.Accept(&accepted_socket, accept_callback.callback());
279   ASSERT_THAT(accept_callback.GetResult(result), IsOk());
280   EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
281   EXPECT_FALSE(socket.WasEverUsed());
282   EXPECT_TRUE(socket.IsConnected());
283 
284   // Write some data to the socket to set WasEverUsed, so that the
285   // socket can be re-used.
286   const char kRequest[] = "GET / HTTP/1.0";
287   auto write_buffer = base::MakeRefCounted<StringIOBuffer>(kRequest);
288   TestCompletionCallback write_callback;
289   socket.Write(write_buffer.get(), write_buffer->size(),
290                write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
291   EXPECT_TRUE(socket.WasEverUsed());
292   socket.Disconnect();
293   EXPECT_FALSE(socket.IsConnected());
294   EXPECT_TRUE(socket.WasEverUsed());
295 
296   // Re-use the socket, and verify that the aliases are still set.
297   EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
298   TestCompletionCallback connect_callback2;
299   connect_result = socket.Connect(connect_callback2.callback());
300   EXPECT_FALSE(socket.WasEverUsed());
301   EXPECT_THAT(socket.GetDnsAliases(),
302               testing::ElementsAre("alias1", "alias2", "host"));
303 }
304 
305 class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
306  public:
307   TestSocketPerformanceWatcher() = default;
308 
309   TestSocketPerformanceWatcher(const TestSocketPerformanceWatcher&) = delete;
310   TestSocketPerformanceWatcher& operator=(const TestSocketPerformanceWatcher&) =
311       delete;
312 
313   ~TestSocketPerformanceWatcher() override = default;
314 
ShouldNotifyUpdatedRTT() const315   bool ShouldNotifyUpdatedRTT() const override { return true; }
316 
OnUpdatedRTTAvailable(const base::TimeDelta & rtt)317   void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {}
318 
OnConnectionChanged()319   void OnConnectionChanged() override { connection_changed_count_++; }
320 
connection_changed_count() const321   size_t connection_changed_count() const { return connection_changed_count_; }
322 
323  private:
324   size_t connection_changed_count_ = 0u;
325 };
326 
327 // TestSocketPerformanceWatcher requires kernel support for tcp_info struct, and
328 // so it is enabled only on certain platforms.
329 #if defined(TCP_INFO) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
330 #define MAYBE_TestSocketPerformanceWatcher TestSocketPerformanceWatcher
331 #else
332 #define MAYBE_TestSocketPerformanceWatcher TestSocketPerformanceWatcher
333 #endif
334 // Tests if the socket performance watcher is notified if the same socket is
335 // used for a different connection.
TEST_F(TCPClientSocketTest,MAYBE_TestSocketPerformanceWatcher)336 TEST_F(TCPClientSocketTest, MAYBE_TestSocketPerformanceWatcher) {
337   const size_t kNumIPs = 2;
338   IPAddressList ip_list;
339   for (size_t i = 0; i < kNumIPs; ++i)
340     ip_list.push_back(IPAddress(72, 14, 213, i));
341 
342   auto watcher = std::make_unique<TestSocketPerformanceWatcher>();
343   TestSocketPerformanceWatcher* watcher_ptr = watcher.get();
344 
345   std::vector<std::string> aliases({"example.com"});
346 
347   TCPClientSocket socket(
348       AddressList::CreateFromIPAddressList(ip_list, std::move(aliases)),
349       std::move(watcher), nullptr, nullptr, NetLogSource());
350 
351   EXPECT_THAT(socket.Bind(IPEndPoint(IPAddress::IPv4Localhost(), 0)), IsOk());
352 
353   TestCompletionCallback connect_callback;
354 
355   ASSERT_NE(OK, connect_callback.GetResult(
356                     socket.Connect(connect_callback.callback())));
357 
358   EXPECT_EQ(kNumIPs - 1, watcher_ptr->connection_changed_count());
359 }
360 
361 // On Android, where socket tagging is supported, verify that
362 // TCPClientSocket::Tag works as expected.
363 #if BUILDFLAG(IS_ANDROID)
TEST_F(TCPClientSocketTest,Tag)364 TEST_F(TCPClientSocketTest, Tag) {
365   if (!CanGetTaggedBytes()) {
366     DVLOG(0) << "Skipping test - GetTaggedBytes unsupported.";
367     return;
368   }
369 
370   // Start test server.
371   EmbeddedTestServer test_server;
372   test_server.AddDefaultHandlers(base::FilePath());
373   ASSERT_TRUE(test_server.Start());
374 
375   AddressList addr_list;
376   ASSERT_TRUE(test_server.GetAddressList(&addr_list));
377   TCPClientSocket s(addr_list, nullptr, nullptr, nullptr, NetLogSource());
378 
379   // Verify TCP connect packets are tagged and counted properly.
380   int32_t tag_val1 = 0x12345678;
381   uint64_t old_traffic = GetTaggedBytes(tag_val1);
382   SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
383   s.ApplySocketTag(tag1);
384   TestCompletionCallback connect_callback;
385   int connect_result = s.Connect(connect_callback.callback());
386   EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
387   EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
388 
389   // Verify socket can be retagged with a new value and the current process's
390   // UID.
391   int32_t tag_val2 = 0x87654321;
392   old_traffic = GetTaggedBytes(tag_val2);
393   SocketTag tag2(getuid(), tag_val2);
394   s.ApplySocketTag(tag2);
395   const char kRequest1[] = "GET / HTTP/1.0";
396   auto write_buffer1 = base::MakeRefCounted<StringIOBuffer>(kRequest1);
397   TestCompletionCallback write_callback1;
398   EXPECT_EQ(s.Write(write_buffer1.get(), strlen(kRequest1),
399                     write_callback1.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
400             static_cast<int>(strlen(kRequest1)));
401   EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
402 
403   // Verify socket can be retagged with a new value and the current process's
404   // UID.
405   old_traffic = GetTaggedBytes(tag_val1);
406   s.ApplySocketTag(tag1);
407   const char kRequest2[] = "\n\n";
408   scoped_refptr<IOBufferWithSize> write_buffer2 =
409       base::MakeRefCounted<IOBufferWithSize>(strlen(kRequest2));
410   memmove(write_buffer2->data(), kRequest2, strlen(kRequest2));
411   TestCompletionCallback write_callback2;
412   EXPECT_EQ(s.Write(write_buffer2.get(), strlen(kRequest2),
413                     write_callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
414             static_cast<int>(strlen(kRequest2)));
415   EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
416 
417   s.Disconnect();
418 }
419 
TEST_F(TCPClientSocketTest,TagAfterConnect)420 TEST_F(TCPClientSocketTest, TagAfterConnect) {
421   if (!CanGetTaggedBytes()) {
422     DVLOG(0) << "Skipping test - GetTaggedBytes unsupported.";
423     return;
424   }
425 
426   // Start test server.
427   EmbeddedTestServer test_server;
428   test_server.AddDefaultHandlers(base::FilePath());
429   ASSERT_TRUE(test_server.Start());
430 
431   AddressList addr_list;
432   ASSERT_TRUE(test_server.GetAddressList(&addr_list));
433   TCPClientSocket s(addr_list, nullptr, nullptr, nullptr, NetLogSource());
434 
435   // Connect socket.
436   TestCompletionCallback connect_callback;
437   int connect_result = s.Connect(connect_callback.callback());
438   EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
439 
440   // Verify socket can be tagged with a new value and the current process's
441   // UID.
442   int32_t tag_val2 = 0x87654321;
443   uint64_t old_traffic = GetTaggedBytes(tag_val2);
444   SocketTag tag2(getuid(), tag_val2);
445   s.ApplySocketTag(tag2);
446   const char kRequest1[] = "GET / HTTP/1.0";
447   auto write_buffer1 = base::MakeRefCounted<StringIOBuffer>(kRequest1);
448   TestCompletionCallback write_callback1;
449   EXPECT_EQ(s.Write(write_buffer1.get(), strlen(kRequest1),
450                     write_callback1.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
451             static_cast<int>(strlen(kRequest1)));
452   EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
453 
454   // Verify socket can be retagged with a new value and the current process's
455   // UID.
456   int32_t tag_val1 = 0x12345678;
457   old_traffic = GetTaggedBytes(tag_val1);
458   SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
459   s.ApplySocketTag(tag1);
460   const char kRequest2[] = "\n\n";
461   auto write_buffer2 = base::MakeRefCounted<StringIOBuffer>(kRequest2);
462   TestCompletionCallback write_callback2;
463   EXPECT_EQ(s.Write(write_buffer2.get(), strlen(kRequest2),
464                     write_callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
465             static_cast<int>(strlen(kRequest2)));
466   EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
467 
468   s.Disconnect();
469 }
470 #endif  // BUILDFLAG(IS_ANDROID)
471 
472 // TCP socket that hangs indefinitely when establishing a connection.
473 class NeverConnectingTCPClientSocket : public TCPClientSocket {
474  public:
NeverConnectingTCPClientSocket(const AddressList & addresses,std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,NetworkQualityEstimator * network_quality_estimator,net::NetLog * net_log,const net::NetLogSource & source)475   NeverConnectingTCPClientSocket(
476       const AddressList& addresses,
477       std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
478       NetworkQualityEstimator* network_quality_estimator,
479       net::NetLog* net_log,
480       const net::NetLogSource& source)
481       : TCPClientSocket(addresses,
482                         std::move(socket_performance_watcher),
483                         network_quality_estimator,
484                         net_log,
485                         source) {}
486 
487   // Returns the number of times that ConnectInternal() was called.
connect_internal_counter() const488   int connect_internal_counter() const { return connect_internal_counter_; }
489 
490  private:
ConnectInternal(const IPEndPoint & endpoint)491   int ConnectInternal(const IPEndPoint& endpoint) override {
492     connect_internal_counter_++;
493     return ERR_IO_PENDING;
494   }
495 
496   int connect_internal_counter_ = 0;
497 };
498 
499 // Tests for closing sockets on suspend mode.
500 #if defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND)
501 
502 // Entering suspend mode shouldn't affect sockets that haven't connected yet, or
503 // listening server sockets.
TEST_F(TCPClientSocketTest,SuspendBeforeConnect)504 TEST_F(TCPClientSocketTest, SuspendBeforeConnect) {
505   IPAddress lo_address = IPAddress::IPv4Localhost();
506 
507   TCPServerSocket server(nullptr, NetLogSource());
508   ASSERT_THAT(
509       server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/std::nullopt),
510       IsOk());
511   IPEndPoint server_address;
512   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
513 
514   TCPClientSocket socket(AddressList(server_address), nullptr, nullptr, nullptr,
515                          NetLogSource());
516 
517   EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
518 
519   IPEndPoint local_address_result;
520   EXPECT_THAT(socket.GetLocalAddress(&local_address_result), IsOk());
521   EXPECT_EQ(lo_address, local_address_result.address());
522 
523   TestCompletionCallback accept_callback;
524   std::unique_ptr<StreamSocket> accepted_socket;
525   ASSERT_THAT(server.Accept(&accepted_socket, accept_callback.callback()),
526               IsError(ERR_IO_PENDING));
527 
528   Suspend();
529   // Power notifications happen asynchronously, so have to wait for the socket
530   // to be notified of the suspend event.
531   base::RunLoop().RunUntilIdle();
532 
533   TestCompletionCallback connect_callback;
534   int connect_result = socket.Connect(connect_callback.callback());
535 
536   ASSERT_THAT(accept_callback.WaitForResult(), IsOk());
537 
538   ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
539 
540   EXPECT_TRUE(socket.IsConnected());
541   EXPECT_TRUE(accepted_socket->IsConnected());
542 }
543 
TEST_F(TCPClientSocketTest,SuspendDuringConnect)544 TEST_F(TCPClientSocketTest, SuspendDuringConnect) {
545   IPAddress lo_address = IPAddress::IPv4Localhost();
546 
547   TCPServerSocket server(nullptr, NetLogSource());
548   ASSERT_THAT(
549       server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/std::nullopt),
550       IsOk());
551   IPEndPoint server_address;
552   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
553 
554   NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr,
555                                         nullptr, nullptr, NetLogSource());
556 
557   EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
558 
559   IPEndPoint local_address_result;
560   EXPECT_THAT(socket.GetLocalAddress(&local_address_result), IsOk());
561   EXPECT_EQ(lo_address, local_address_result.address());
562 
563   TestCompletionCallback connect_callback;
564   int rv = socket.Connect(connect_callback.callback());
565   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
566   Suspend();
567   EXPECT_THAT(connect_callback.WaitForResult(),
568               IsError(ERR_NETWORK_IO_SUSPENDED));
569 }
570 
TEST_F(TCPClientSocketTest,SuspendDuringConnectMultipleAddresses)571 TEST_F(TCPClientSocketTest, SuspendDuringConnectMultipleAddresses) {
572   IPAddress lo_address = IPAddress::IPv4Localhost();
573 
574   TCPServerSocket server(nullptr, NetLogSource());
575   ASSERT_THAT(server.Listen(IPEndPoint(IPAddress(0, 0, 0, 0), 0), 1,
576                             /*ipv6_only=*/std::nullopt),
577               IsOk());
578   IPEndPoint server_address;
579   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
580 
581   AddressList address_list;
582   address_list.push_back(
583       IPEndPoint(IPAddress(127, 0, 0, 1), server_address.port()));
584   address_list.push_back(
585       IPEndPoint(IPAddress(127, 0, 0, 2), server_address.port()));
586   NeverConnectingTCPClientSocket socket(address_list, nullptr, nullptr, nullptr,
587                                         NetLogSource());
588 
589   EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk());
590 
591   IPEndPoint local_address_result;
592   EXPECT_THAT(socket.GetLocalAddress(&local_address_result), IsOk());
593   EXPECT_EQ(lo_address, local_address_result.address());
594 
595   TestCompletionCallback connect_callback;
596   int rv = socket.Connect(connect_callback.callback());
597   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
598   Suspend();
599   EXPECT_THAT(connect_callback.WaitForResult(),
600               IsError(ERR_NETWORK_IO_SUSPENDED));
601 }
602 
TEST_F(TCPClientSocketTest,SuspendWhileIdle)603 TEST_F(TCPClientSocketTest, SuspendWhileIdle) {
604   std::unique_ptr<StreamSocket> accepted_socket;
605   std::unique_ptr<TCPClientSocket> client_socket;
606   std::unique_ptr<ServerSocket> server_socket;
607   CreateConnectedSockets(&accepted_socket, &client_socket, &server_socket);
608 
609   Suspend();
610   // Power notifications happen asynchronously.
611   base::RunLoop().RunUntilIdle();
612 
613   auto buffer = base::MakeRefCounted<IOBufferWithSize>(1);
614   buffer->data()[0] = '1';
615   TestCompletionCallback callback;
616   // Check that the client socket is disconnected, and actions fail with
617   // ERR_NETWORK_IO_SUSPENDED.
618   EXPECT_FALSE(client_socket->IsConnected());
619   EXPECT_THAT(client_socket->Read(buffer.get(), 1, callback.callback()),
620               IsError(ERR_NETWORK_IO_SUSPENDED));
621   EXPECT_THAT(client_socket->Write(buffer.get(), 1, callback.callback(),
622                                    TRAFFIC_ANNOTATION_FOR_TESTS),
623               IsError(ERR_NETWORK_IO_SUSPENDED));
624 
625   // Check that the accepted socket is disconnected, and actions fail with
626   // ERR_NETWORK_IO_SUSPENDED.
627   EXPECT_FALSE(accepted_socket->IsConnected());
628   EXPECT_THAT(accepted_socket->Read(buffer.get(), 1, callback.callback()),
629               IsError(ERR_NETWORK_IO_SUSPENDED));
630   EXPECT_THAT(accepted_socket->Write(buffer.get(), 1, callback.callback(),
631                                      TRAFFIC_ANNOTATION_FOR_TESTS),
632               IsError(ERR_NETWORK_IO_SUSPENDED));
633 
634   // Reconnecting the socket should work.
635   TestCompletionCallback connect_callback;
636   int connect_result = client_socket->Connect(connect_callback.callback());
637   accepted_socket.reset();
638   TestCompletionCallback accept_callback;
639   int accept_result =
640       server_socket->Accept(&accepted_socket, accept_callback.callback());
641   ASSERT_THAT(accept_callback.GetResult(accept_result), IsOk());
642   EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
643 }
644 
TEST_F(TCPClientSocketTest,SuspendDuringRead)645 TEST_F(TCPClientSocketTest, SuspendDuringRead) {
646   std::unique_ptr<StreamSocket> accepted_socket;
647   std::unique_ptr<TCPClientSocket> client_socket;
648   CreateConnectedSockets(&accepted_socket, &client_socket);
649 
650   // Start a read. This shouldn't complete, since the other end of the pipe
651   // writes no data.
652   auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(1);
653   read_buffer->data()[0] = '1';
654   TestCompletionCallback callback;
655   ASSERT_THAT(client_socket->Read(read_buffer.get(), 1, callback.callback()),
656               IsError(ERR_IO_PENDING));
657 
658   // Simulate a suspend event. Can't use a real power event, as it would affect
659   // |accepted_socket| as well.
660   client_socket->OnSuspend();
661   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_IO_SUSPENDED));
662 
663   // Check that the client socket really is disconnected.
664   EXPECT_FALSE(client_socket->IsConnected());
665   EXPECT_THAT(client_socket->Read(read_buffer.get(), 1, callback.callback()),
666               IsError(ERR_NETWORK_IO_SUSPENDED));
667   EXPECT_THAT(client_socket->Write(read_buffer.get(), 1, callback.callback(),
668                                    TRAFFIC_ANNOTATION_FOR_TESTS),
669               IsError(ERR_NETWORK_IO_SUSPENDED));
670 }
671 
TEST_F(TCPClientSocketTest,SuspendDuringWrite)672 TEST_F(TCPClientSocketTest, SuspendDuringWrite) {
673   std::unique_ptr<StreamSocket> accepted_socket;
674   std::unique_ptr<TCPClientSocket> client_socket;
675   CreateConnectedSockets(&accepted_socket, &client_socket);
676 
677   // Write to the socket until a write doesn't complete synchronously.
678   const int kBufferSize = 4096;
679   auto write_buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
680   memset(write_buffer->data(), '1', kBufferSize);
681   TestCompletionCallback callback;
682   while (true) {
683     int rv =
684         client_socket->Write(write_buffer.get(), kBufferSize,
685                              callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
686     if (rv == ERR_IO_PENDING)
687       break;
688     ASSERT_GT(rv, 0);
689   }
690 
691   // Simulate a suspend event. Can't use a real power event, as it would affect
692   // |accepted_socket| as well.
693   client_socket->OnSuspend();
694   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_IO_SUSPENDED));
695 
696   // Check that the client socket really is disconnected.
697   EXPECT_FALSE(client_socket->IsConnected());
698   EXPECT_THAT(client_socket->Read(write_buffer.get(), 1, callback.callback()),
699               IsError(ERR_NETWORK_IO_SUSPENDED));
700   EXPECT_THAT(client_socket->Write(write_buffer.get(), 1, callback.callback(),
701                                    TRAFFIC_ANNOTATION_FOR_TESTS),
702               IsError(ERR_NETWORK_IO_SUSPENDED));
703 }
704 
TEST_F(TCPClientSocketTest,SuspendDuringReadAndWrite)705 TEST_F(TCPClientSocketTest, SuspendDuringReadAndWrite) {
706   enum class ReadCallbackAction {
707     kNone,
708     kDestroySocket,
709     kDisconnectSocket,
710     kReconnectSocket,
711   };
712 
713   for (ReadCallbackAction read_callback_action : {
714            ReadCallbackAction::kNone,
715            ReadCallbackAction::kDestroySocket,
716            ReadCallbackAction::kDisconnectSocket,
717            ReadCallbackAction::kReconnectSocket,
718        }) {
719     std::unique_ptr<StreamSocket> accepted_socket;
720     std::unique_ptr<TCPClientSocket> client_socket;
721     std::unique_ptr<ServerSocket> server_socket;
722     CreateConnectedSockets(&accepted_socket, &client_socket, &server_socket);
723 
724     // Start a read. This shouldn't complete, since the other end of the pipe
725     // writes no data.
726     auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(1);
727     read_buffer->data()[0] = '1';
728     TestCompletionCallback read_callback;
729 
730     // Used int the ReadCallbackAction::kReconnectSocket case, since can't run a
731     // nested message loop in the read callback.
732     TestCompletionCallback nested_connect_callback;
733     int nested_connect_result;
734 
735     CompletionOnceCallback read_completion_once_callback =
736         base::BindLambdaForTesting([&](int result) {
737           EXPECT_FALSE(client_socket->IsConnected());
738           switch (read_callback_action) {
739             case ReadCallbackAction::kNone:
740               break;
741             case ReadCallbackAction::kDestroySocket:
742               client_socket.reset();
743               break;
744             case ReadCallbackAction::kDisconnectSocket:
745               client_socket->Disconnect();
746               break;
747             case ReadCallbackAction::kReconnectSocket: {
748               TestCompletionCallback connect_callback;
749               nested_connect_result =
750                   client_socket->Connect(nested_connect_callback.callback());
751               break;
752             }
753           }
754           read_callback.callback().Run(result);
755         });
756     ASSERT_THAT(client_socket->Read(read_buffer.get(), 1,
757                                     std::move(read_completion_once_callback)),
758                 IsError(ERR_IO_PENDING));
759 
760     // Write to the socket until a write doesn't complete synchronously.
761     const int kBufferSize = 4096;
762     auto write_buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
763     memset(write_buffer->data(), '1', kBufferSize);
764     TestCompletionCallback write_callback;
765     while (true) {
766       int rv = client_socket->Write(write_buffer.get(), kBufferSize,
767                                     write_callback.callback(),
768                                     TRAFFIC_ANNOTATION_FOR_TESTS);
769       if (rv == ERR_IO_PENDING)
770         break;
771       ASSERT_GT(rv, 0);
772     }
773 
774     // Simulate a suspend event. Can't use a real power event, as it would
775     // affect |accepted_socket| as well.
776     client_socket->OnSuspend();
777     EXPECT_THAT(read_callback.WaitForResult(),
778                 IsError(ERR_NETWORK_IO_SUSPENDED));
779     if (read_callback_action == ReadCallbackAction::kNone) {
780       EXPECT_THAT(write_callback.WaitForResult(),
781                   IsError(ERR_NETWORK_IO_SUSPENDED));
782 
783       // Check that the client socket really is disconnected.
784       EXPECT_FALSE(client_socket->IsConnected());
785       EXPECT_THAT(
786           client_socket->Read(read_buffer.get(), 1, read_callback.callback()),
787           IsError(ERR_NETWORK_IO_SUSPENDED));
788       EXPECT_THAT(
789           client_socket->Write(write_buffer.get(), 1, write_callback.callback(),
790                                TRAFFIC_ANNOTATION_FOR_TESTS),
791           IsError(ERR_NETWORK_IO_SUSPENDED));
792     } else {
793       // Each of the actions taken in the read callback will cancel the pending
794       // write callback.
795       EXPECT_FALSE(write_callback.have_result());
796     }
797 
798     if (read_callback_action == ReadCallbackAction::kReconnectSocket) {
799       // Finish establishing a connection, just to make sure the reconnect case
800       // completely works.
801       accepted_socket.reset();
802       TestCompletionCallback accept_callback;
803       int accept_result =
804           server_socket->Accept(&accepted_socket, accept_callback.callback());
805       ASSERT_THAT(accept_callback.GetResult(accept_result), IsOk());
806       EXPECT_THAT(nested_connect_callback.GetResult(nested_connect_result),
807                   IsOk());
808     }
809   }
810 }
811 
812 #endif  // defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND)
813 
814 // Scoped helper to override the TCP connect attempt policy.
815 class OverrideTcpConnectAttemptTimeout {
816  public:
OverrideTcpConnectAttemptTimeout(double rtt_multipilier,base::TimeDelta min_timeout,base::TimeDelta max_timeout)817   OverrideTcpConnectAttemptTimeout(double rtt_multipilier,
818                                    base::TimeDelta min_timeout,
819                                    base::TimeDelta max_timeout) {
820     base::FieldTrialParams params;
821     params[features::kTimeoutTcpConnectAttemptRTTMultiplier.name] =
822         base::NumberToString(rtt_multipilier);
823     params[features::kTimeoutTcpConnectAttemptMin.name] =
824         base::NumberToString(min_timeout.InMilliseconds()) + "ms";
825     params[features::kTimeoutTcpConnectAttemptMax.name] =
826         base::NumberToString(max_timeout.InMilliseconds()) + "ms";
827 
828     scoped_feature_list_.InitAndEnableFeatureWithParameters(
829         features::kTimeoutTcpConnectAttempt, params);
830   }
831 
832  private:
833   base::test::ScopedFeatureList scoped_feature_list_;
834 };
835 
836 // Test fixture that uses a MOCK_TIME test environment, so time can
837 // be advanced programmatically.
838 class TCPClientSocketMockTimeTest : public testing::Test {
839  public:
TCPClientSocketMockTimeTest()840   TCPClientSocketMockTimeTest()
841       : task_environment_(base::test::TaskEnvironment::MainThreadType::IO,
842                           base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
843 
844  protected:
845   base::test::TaskEnvironment task_environment_;
846 };
847 
848 // Tests that no TCP connect timeout is enforced by default (i.e.
849 // when the feature is disabled).
TEST_F(TCPClientSocketMockTimeTest,NoConnectAttemptTimeoutByDefault)850 TEST_F(TCPClientSocketMockTimeTest, NoConnectAttemptTimeoutByDefault) {
851   IPEndPoint server_address(IPAddress::IPv4Localhost(), 80);
852   NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr,
853                                         nullptr, nullptr, NetLogSource());
854 
855   TestCompletionCallback connect_callback;
856   int rv = socket.Connect(connect_callback.callback());
857   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
858 
859   // After 4 minutes, the socket should still be connecting.
860   task_environment_.FastForwardBy(base::Minutes(4));
861   EXPECT_FALSE(connect_callback.have_result());
862   EXPECT_FALSE(socket.IsConnected());
863 
864   // 1 attempt was made.
865   EXPECT_EQ(1, socket.connect_internal_counter());
866 }
867 
868 // Tests that the maximum timeout is used when there is no estimated
869 // RTT.
TEST_F(TCPClientSocketMockTimeTest,ConnectAttemptTimeoutUsesMaxWhenNoRTT)870 TEST_F(TCPClientSocketMockTimeTest, ConnectAttemptTimeoutUsesMaxWhenNoRTT) {
871   OverrideTcpConnectAttemptTimeout override_timeout(1, base::Seconds(4),
872                                                     base::Seconds(10));
873 
874   IPEndPoint server_address(IPAddress::IPv4Localhost(), 80);
875 
876   // Pass a null NetworkQualityEstimator, so the TCPClientSocket is unable to
877   // estimate the RTT.
878   NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr,
879                                         nullptr, nullptr, NetLogSource());
880 
881   // Start connecting.
882   TestCompletionCallback connect_callback;
883   int rv = socket.Connect(connect_callback.callback());
884   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
885 
886   // Advance to t=3.1s
887   // Should still be pending, as this is before the minimum timeout.
888   task_environment_.FastForwardBy(base::Milliseconds(3100));
889   EXPECT_FALSE(connect_callback.have_result());
890   EXPECT_FALSE(socket.IsConnected());
891 
892   // Advance to t=4.1s
893   // Should still be pending. This is after the minimum timeout, but before the
894   // maximum.
895   task_environment_.FastForwardBy(base::Seconds(1));
896   EXPECT_FALSE(connect_callback.have_result());
897   EXPECT_FALSE(socket.IsConnected());
898 
899   // Advance to t=10.1s
900   // Should now be timed out, as this is after the maximum timeout.
901   task_environment_.FastForwardBy(base::Seconds(6));
902   rv = connect_callback.GetResult(rv);
903   ASSERT_THAT(rv, IsError(ERR_TIMED_OUT));
904 
905   // 1 attempt was made.
906   EXPECT_EQ(1, socket.connect_internal_counter());
907 }
908 
909 // Tests that the minimum timeout is used when the adaptive timeout using RTT
910 // ends up being too low.
TEST_F(TCPClientSocketMockTimeTest,ConnectAttemptTimeoutUsesMinWhenRTTLow)911 TEST_F(TCPClientSocketMockTimeTest, ConnectAttemptTimeoutUsesMinWhenRTTLow) {
912   OverrideTcpConnectAttemptTimeout override_timeout(5, base::Seconds(4),
913                                                     base::Seconds(10));
914 
915   // Set the estimated RTT to 1 millisecond.
916   TestNetworkQualityEstimator network_quality_estimator;
917   network_quality_estimator.SetStartTimeNullTransportRtt(base::Milliseconds(1));
918 
919   IPEndPoint server_address(IPAddress::IPv4Localhost(), 80);
920 
921   NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr,
922                                         &network_quality_estimator, nullptr,
923                                         NetLogSource());
924 
925   // Start connecting.
926   TestCompletionCallback connect_callback;
927   int rv = socket.Connect(connect_callback.callback());
928   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
929 
930   // Advance to t=1.1s
931   // Should be pending, since although the adaptive timeout has been reached, it
932   // is lower than the minimum timeout.
933   task_environment_.FastForwardBy(base::Milliseconds(1100));
934   EXPECT_FALSE(connect_callback.have_result());
935   EXPECT_FALSE(socket.IsConnected());
936 
937   // Advance to t=4.1s
938   // Should have timed out due to hitting the minimum timeout.
939   task_environment_.FastForwardBy(base::Seconds(3));
940   rv = connect_callback.GetResult(rv);
941   ASSERT_THAT(rv, IsError(ERR_TIMED_OUT));
942 
943   // 1 attempt was made.
944   EXPECT_EQ(1, socket.connect_internal_counter());
945 }
946 
947 // Tests that the maximum timeout is used when the adaptive timeout from RTT is
948 // too high.
TEST_F(TCPClientSocketMockTimeTest,ConnectAttemptTimeoutUsesMinWhenRTTHigh)949 TEST_F(TCPClientSocketMockTimeTest, ConnectAttemptTimeoutUsesMinWhenRTTHigh) {
950   OverrideTcpConnectAttemptTimeout override_timeout(5, base::Seconds(4),
951                                                     base::Seconds(10));
952 
953   // Set the estimated RTT to 5 seconds.
954   TestNetworkQualityEstimator network_quality_estimator;
955   network_quality_estimator.SetStartTimeNullTransportRtt(base::Seconds(5));
956 
957   IPEndPoint server_address(IPAddress::IPv4Localhost(), 80);
958 
959   NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr,
960                                         &network_quality_estimator, nullptr,
961                                         NetLogSource());
962 
963   // Start connecting.
964   TestCompletionCallback connect_callback;
965   int rv = socket.Connect(connect_callback.callback());
966   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
967 
968   // Advance to t=10.1s
969   // The socket should have timed out due to hitting the maximum timeout. Had
970   // the adaptive timeout been used, the socket would instead be timing out at
971   // t=25s.
972   task_environment_.FastForwardBy(base::Milliseconds(10100));
973   rv = connect_callback.GetResult(rv);
974   ASSERT_THAT(rv, IsError(ERR_TIMED_OUT));
975 
976   // 1 attempt was made.
977   EXPECT_EQ(1, socket.connect_internal_counter());
978 }
979 
980 // Tests that an adaptive timeout is used for TCP connection attempts based on
981 // the estimated RTT.
TEST_F(TCPClientSocketMockTimeTest,ConnectAttemptTimeoutUsesRTT)982 TEST_F(TCPClientSocketMockTimeTest, ConnectAttemptTimeoutUsesRTT) {
983   OverrideTcpConnectAttemptTimeout override_timeout(5, base::Seconds(4),
984                                                     base::Seconds(10));
985 
986   // Set the estimated RTT to 1 second. Since the multiplier is set to 5, the
987   // total adaptive timeout will be 5 seconds.
988   TestNetworkQualityEstimator network_quality_estimator;
989   network_quality_estimator.SetStartTimeNullTransportRtt(base::Seconds(1));
990 
991   IPEndPoint server_address(IPAddress::IPv4Localhost(), 80);
992 
993   NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr,
994                                         &network_quality_estimator, nullptr,
995                                         NetLogSource());
996 
997   // Start connecting.
998   TestCompletionCallback connect_callback;
999   int rv = socket.Connect(connect_callback.callback());
1000   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1001 
1002   // Advance to t=4.1s
1003   // The socket should still be pending. Had the minimum timeout been enforced,
1004   // it would instead have timed out now.
1005   task_environment_.FastForwardBy(base::Milliseconds(4100));
1006   EXPECT_FALSE(connect_callback.have_result());
1007   EXPECT_FALSE(socket.IsConnected());
1008 
1009   // Advance to t=5.1s
1010   // The adaptive timeout was at t=5s, so it should now be timed out.
1011   task_environment_.FastForwardBy(base::Seconds(1));
1012   rv = connect_callback.GetResult(rv);
1013   ASSERT_THAT(rv, IsError(ERR_TIMED_OUT));
1014 
1015   // 1 attempt was made.
1016   EXPECT_EQ(1, socket.connect_internal_counter());
1017 }
1018 
1019 // Tests that when multiple TCP connect attempts are made, the timeout for each
1020 // one is applied independently.
TEST_F(TCPClientSocketMockTimeTest,ConnectAttemptTimeoutIndependent)1021 TEST_F(TCPClientSocketMockTimeTest, ConnectAttemptTimeoutIndependent) {
1022   OverrideTcpConnectAttemptTimeout override_timeout(5, base::Seconds(4),
1023                                                     base::Seconds(10));
1024 
1025   // This test will attempt connecting to 5 endpoints.
1026   const size_t kNumIps = 5;
1027 
1028   AddressList addresses;
1029   for (size_t i = 0; i < kNumIps; ++i)
1030     addresses.push_back(IPEndPoint(IPAddress::IPv4Localhost(), 80 + i));
1031 
1032   NeverConnectingTCPClientSocket socket(addresses, nullptr, nullptr, nullptr,
1033                                         NetLogSource());
1034 
1035   // Start connecting.
1036   TestCompletionCallback connect_callback;
1037   int rv = socket.Connect(connect_callback.callback());
1038   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1039 
1040   // Advance to t=49s
1041   // Should still be pending.
1042   task_environment_.FastForwardBy(base::Seconds(49));
1043   EXPECT_FALSE(connect_callback.have_result());
1044   EXPECT_FALSE(socket.IsConnected());
1045 
1046   // Advance to t=50.1s
1047   // All attempts should take 50 seconds to complete (5 attempts, 10 seconds
1048   // each). So by this point the overall connect attempt will have timed out.
1049   task_environment_.FastForwardBy(base::Milliseconds(1100));
1050   rv = connect_callback.GetResult(rv);
1051   ASSERT_THAT(rv, IsError(ERR_TIMED_OUT));
1052 
1053   // 5 attempts were made.
1054   EXPECT_EQ(5, socket.connect_internal_counter());
1055 }
1056 
1057 }  // namespace
1058 
1059 }  // namespace net
1060