xref: /aosp_15_r20/external/cronet/net/nqe/socket_watcher_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2017 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 "net/nqe/socket_watcher.h"
6 
7 #include "base/functional/bind.h"
8 #include "base/run_loop.h"
9 #include "base/task/single_thread_task_runner.h"
10 #include "base/test/simple_test_tick_clock.h"
11 #include "base/time/time.h"
12 #include "build/build_config.h"
13 #include "net/base/ip_address.h"
14 #include "net/socket/socket_performance_watcher_factory.h"
15 #include "net/test/test_with_task_environment.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 
18 namespace net::nqe::internal {
19 
20 namespace {
21 
22 class NetworkQualitySocketWatcherTest : public TestWithTaskEnvironment {
23  public:
24   NetworkQualitySocketWatcherTest(const NetworkQualitySocketWatcherTest&) =
25       delete;
26   NetworkQualitySocketWatcherTest& operator=(
27       const NetworkQualitySocketWatcherTest&) = delete;
28 
29  protected:
NetworkQualitySocketWatcherTest()30   NetworkQualitySocketWatcherTest() { ResetExpectedCallbackParams(); }
~NetworkQualitySocketWatcherTest()31   ~NetworkQualitySocketWatcherTest() override { ResetExpectedCallbackParams(); }
32 
OnUpdatedRTTAvailableStoreParams(SocketPerformanceWatcherFactory::Protocol protocol,const base::TimeDelta & rtt,const std::optional<IPHash> & host)33   static void OnUpdatedRTTAvailableStoreParams(
34       SocketPerformanceWatcherFactory::Protocol protocol,
35       const base::TimeDelta& rtt,
36       const std::optional<IPHash>& host) {
37     // Need to verify before another callback is executed, or explicitly call
38     // |ResetCallbackParams()|.
39     ASSERT_FALSE(callback_executed_);
40     callback_rtt_ = rtt;
41     callback_host_ = host;
42     callback_executed_ = true;
43   }
44 
OnUpdatedRTTAvailable(SocketPerformanceWatcherFactory::Protocol protocol,const base::TimeDelta & rtt,const std::optional<IPHash> & host)45   static void OnUpdatedRTTAvailable(
46       SocketPerformanceWatcherFactory::Protocol protocol,
47       const base::TimeDelta& rtt,
48       const std::optional<IPHash>& host) {
49     // Need to verify before another callback is executed, or explicitly call
50     // |ResetCallbackParams()|.
51     ASSERT_FALSE(callback_executed_);
52     callback_executed_ = true;
53   }
54 
SetShouldNotifyRTTCallback(bool value)55   static void SetShouldNotifyRTTCallback(bool value) {
56     should_notify_rtt_callback_ = value;
57   }
58 
ShouldNotifyRTTCallback(base::TimeTicks now)59   static bool ShouldNotifyRTTCallback(base::TimeTicks now) {
60     return should_notify_rtt_callback_;
61   }
62 
VerifyCallbackParams(const base::TimeDelta & rtt,const std::optional<IPHash> & host)63   static void VerifyCallbackParams(const base::TimeDelta& rtt,
64                                    const std::optional<IPHash>& host) {
65     ASSERT_TRUE(callback_executed_);
66     EXPECT_EQ(rtt, callback_rtt_);
67     if (host)
68       EXPECT_EQ(host, callback_host_);
69     else
70       EXPECT_FALSE(callback_host_.has_value());
71     ResetExpectedCallbackParams();
72   }
73 
ResetExpectedCallbackParams()74   static void ResetExpectedCallbackParams() {
75     callback_rtt_ = base::Milliseconds(0);
76     callback_host_ = std::nullopt;
77     callback_executed_ = false;
78     should_notify_rtt_callback_ = false;
79   }
80 
callback_rtt()81   static base::TimeDelta callback_rtt() { return callback_rtt_; }
82 
83  private:
84   static base::TimeDelta callback_rtt_;
85   static std::optional<IPHash> callback_host_;
86   static bool callback_executed_;
87   static bool should_notify_rtt_callback_;
88 };
89 
90 base::TimeDelta NetworkQualitySocketWatcherTest::callback_rtt_ =
91     base::Milliseconds(0);
92 
93 std::optional<IPHash> NetworkQualitySocketWatcherTest::callback_host_ =
94     std::nullopt;
95 
96 bool NetworkQualitySocketWatcherTest::callback_executed_ = false;
97 
98 bool NetworkQualitySocketWatcherTest::should_notify_rtt_callback_ = false;
99 
100 // Verify that the buffer size is never exceeded.
TEST_F(NetworkQualitySocketWatcherTest,NotificationsThrottled)101 TEST_F(NetworkQualitySocketWatcherTest, NotificationsThrottled) {
102   base::SimpleTestTickClock tick_clock;
103   tick_clock.SetNowTicks(base::TimeTicks::Now());
104 
105   // Use a public IP address so that the socket watcher runs the RTT callback.
106   IPAddress ip_address;
107   ASSERT_TRUE(ip_address.AssignFromIPLiteral("157.0.0.1"));
108 
109   SocketWatcher socket_watcher(
110       SocketPerformanceWatcherFactory::PROTOCOL_TCP, ip_address,
111       base::Milliseconds(2000), false,
112       base::SingleThreadTaskRunner::GetCurrentDefault(),
113       base::BindRepeating(OnUpdatedRTTAvailable),
114       base::BindRepeating(ShouldNotifyRTTCallback), &tick_clock);
115 
116   EXPECT_TRUE(socket_watcher.ShouldNotifyUpdatedRTT());
117   socket_watcher.OnUpdatedRTTAvailable(base::Seconds(10));
118   base::RunLoop().RunUntilIdle();
119   ResetExpectedCallbackParams();
120 
121   EXPECT_FALSE(socket_watcher.ShouldNotifyUpdatedRTT());
122 
123   tick_clock.Advance(base::Milliseconds(1000));
124   // Minimum interval between consecutive notifications is 2000 msec.
125   EXPECT_FALSE(socket_watcher.ShouldNotifyUpdatedRTT());
126 
127   // Advance the clock by 1000 msec more so that the current time is at least
128   // 2000 msec more than the last time |socket_watcher| received a notification.
129   tick_clock.Advance(base::Milliseconds(1000));
130   EXPECT_TRUE(socket_watcher.ShouldNotifyUpdatedRTT());
131   ResetExpectedCallbackParams();
132   socket_watcher.OnUpdatedRTTAvailable(base::Seconds(10));
133 
134   EXPECT_FALSE(socket_watcher.ShouldNotifyUpdatedRTT());
135 
136   // RTT notification is allowed by the global check.
137   SetShouldNotifyRTTCallback(true);
138   EXPECT_TRUE(socket_watcher.ShouldNotifyUpdatedRTT());
139 }
140 
TEST_F(NetworkQualitySocketWatcherTest,QuicFirstNotificationDropped)141 TEST_F(NetworkQualitySocketWatcherTest, QuicFirstNotificationDropped) {
142   base::SimpleTestTickClock tick_clock;
143   tick_clock.SetNowTicks(base::TimeTicks::Now());
144 
145   // Use a public IP address so that the socket watcher runs the RTT callback.
146   IPAddress ip_address;
147   ASSERT_TRUE(ip_address.AssignFromIPLiteral("157.0.0.1"));
148 
149   SocketWatcher socket_watcher(
150       SocketPerformanceWatcherFactory::PROTOCOL_QUIC, ip_address,
151       base::Milliseconds(2000), false,
152       base::SingleThreadTaskRunner::GetCurrentDefault(),
153       base::BindRepeating(OnUpdatedRTTAvailableStoreParams),
154       base::BindRepeating(ShouldNotifyRTTCallback), &tick_clock);
155 
156   EXPECT_TRUE(socket_watcher.ShouldNotifyUpdatedRTT());
157   socket_watcher.OnUpdatedRTTAvailable(base::Seconds(10));
158   base::RunLoop().RunUntilIdle();
159   // First notification from a QUIC connection should be dropped, and it should
160   // be possible to notify the |socket_watcher| again.
161   EXPECT_TRUE(NetworkQualitySocketWatcherTest::callback_rtt().is_zero());
162   EXPECT_TRUE(socket_watcher.ShouldNotifyUpdatedRTT());
163   ResetExpectedCallbackParams();
164 
165   socket_watcher.OnUpdatedRTTAvailable(base::Seconds(2));
166   base::RunLoop().RunUntilIdle();
167   EXPECT_EQ(base::Seconds(2), NetworkQualitySocketWatcherTest::callback_rtt());
168   ResetExpectedCallbackParams();
169 
170   EXPECT_FALSE(socket_watcher.ShouldNotifyUpdatedRTT());
171 
172   tick_clock.Advance(base::Milliseconds(1000));
173   // Minimum interval between consecutive notifications is 2000 msec.
174   EXPECT_FALSE(socket_watcher.ShouldNotifyUpdatedRTT());
175 
176   // Advance the clock by 1000 msec more so that the current time is at least
177   // 2000 msec more than the last time |socket_watcher| received a notification.
178   tick_clock.Advance(base::Milliseconds(1000));
179   EXPECT_TRUE(socket_watcher.ShouldNotifyUpdatedRTT());
180 }
181 
182 #if BUILDFLAG(IS_IOS)
183 // Flaky on iOS: crbug.com/672917.
184 #define MAYBE_PrivateAddressRTTNotNotified DISABLED_PrivateAddressRTTNotNotified
185 #else
186 #define MAYBE_PrivateAddressRTTNotNotified PrivateAddressRTTNotNotified
187 #endif
TEST_F(NetworkQualitySocketWatcherTest,MAYBE_PrivateAddressRTTNotNotified)188 TEST_F(NetworkQualitySocketWatcherTest, MAYBE_PrivateAddressRTTNotNotified) {
189   base::SimpleTestTickClock tick_clock;
190   tick_clock.SetNowTicks(base::TimeTicks::Now());
191 
192   const struct {
193     std::string ip_address;
194     bool expect_should_notify_rtt;
195   } tests[] = {
196       {"157.0.0.1", true},    {"127.0.0.1", false},
197       {"192.168.0.1", false}, {"::1", false},
198       {"0.0.0.0", false},     {"2607:f8b0:4006:819::200e", true},
199   };
200 
201   for (const auto& test : tests) {
202     IPAddress ip_address;
203     ASSERT_TRUE(ip_address.AssignFromIPLiteral(test.ip_address));
204 
205     SocketWatcher socket_watcher(
206         SocketPerformanceWatcherFactory::PROTOCOL_TCP, ip_address,
207         base::Milliseconds(2000), false,
208         base::SingleThreadTaskRunner::GetCurrentDefault(),
209         base::BindRepeating(OnUpdatedRTTAvailable),
210         base::BindRepeating(ShouldNotifyRTTCallback), &tick_clock);
211 
212     EXPECT_EQ(test.expect_should_notify_rtt,
213               socket_watcher.ShouldNotifyUpdatedRTT());
214     socket_watcher.OnUpdatedRTTAvailable(base::Seconds(10));
215     base::RunLoop().RunUntilIdle();
216     ResetExpectedCallbackParams();
217 
218     EXPECT_FALSE(socket_watcher.ShouldNotifyUpdatedRTT());
219   }
220 }
221 
TEST_F(NetworkQualitySocketWatcherTest,RemoteHostIPHashComputedCorrectly)222 TEST_F(NetworkQualitySocketWatcherTest, RemoteHostIPHashComputedCorrectly) {
223   base::SimpleTestTickClock tick_clock;
224   tick_clock.SetNowTicks(base::TimeTicks::Now());
225   const struct {
226     std::string ip_address;
227     uint64_t host;
228   } tests[] = {
229       {"112.112.112.100", 0x0000000070707064UL},  // IPv4.
230       {"112.112.112.250", 0x00000000707070faUL},
231       {"2001:0db8:85a3:0000:0000:8a2e:0370:7334",
232        0x20010db885a30000UL},                                 // IPv6.
233       {"2001:db8:85a3::8a2e:370:7334", 0x20010db885a30000UL}  // Shortened IPv6.
234   };
235 
236   for (const auto& test : tests) {
237     IPAddress ip_address;
238     ASSERT_TRUE(ip_address.AssignFromIPLiteral(test.ip_address));
239 
240     SocketWatcher socket_watcher(
241         SocketPerformanceWatcherFactory::PROTOCOL_TCP, ip_address,
242         base::Milliseconds(2000), false,
243         base::SingleThreadTaskRunner::GetCurrentDefault(),
244         base::BindRepeating(OnUpdatedRTTAvailableStoreParams),
245         base::BindRepeating(ShouldNotifyRTTCallback), &tick_clock);
246     EXPECT_TRUE(socket_watcher.ShouldNotifyUpdatedRTT());
247     socket_watcher.OnUpdatedRTTAvailable(base::Seconds(10));
248     base::RunLoop().RunUntilIdle();
249     VerifyCallbackParams(base::Seconds(10), test.host);
250     EXPECT_FALSE(socket_watcher.ShouldNotifyUpdatedRTT());
251   }
252 }
253 
254 }  // namespace
255 
256 }  // namespace net::nqe::internal
257