xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/congestion_control/rtt_stats.h"
6 
7 #include <cmath>
8 
9 #include "quiche/quic/platform/api/quic_test.h"
10 #include "quiche/quic/test_tools/quic_test_utils.h"
11 
12 using testing::Message;
13 
14 namespace quic {
15 namespace test {
16 
17 class RttStatsTest : public QuicTest {
18  protected:
19   RttStats rtt_stats_;
20 };
21 
TEST_F(RttStatsTest,DefaultsBeforeUpdate)22 TEST_F(RttStatsTest, DefaultsBeforeUpdate) {
23   EXPECT_LT(QuicTime::Delta::Zero(), rtt_stats_.initial_rtt());
24   EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.min_rtt());
25   EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.smoothed_rtt());
26 }
27 
TEST_F(RttStatsTest,SmoothedRtt)28 TEST_F(RttStatsTest, SmoothedRtt) {
29   // Verify that ack_delay is ignored in the first measurement.
30   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
31                        QuicTime::Delta::FromMilliseconds(100),
32                        QuicTime::Zero());
33   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
34   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
35   // Verify that a plausible ack delay increases the max ack delay.
36   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(400),
37                        QuicTime::Delta::FromMilliseconds(100),
38                        QuicTime::Zero());
39   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
40   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
41   // Verify that Smoothed RTT includes max ack delay if it's reasonable.
42   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(350),
43                        QuicTime::Delta::FromMilliseconds(50), QuicTime::Zero());
44   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
45   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
46   // Verify that large erroneous ack_delay does not change Smoothed RTT.
47   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
48                        QuicTime::Delta::FromMilliseconds(300),
49                        QuicTime::Zero());
50   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
51   EXPECT_EQ(QuicTime::Delta::FromMicroseconds(287500),
52             rtt_stats_.smoothed_rtt());
53 }
54 
55 // Ensure that the potential rounding artifacts in EWMA calculation do not cause
56 // the SRTT to drift too far from the exact value.
TEST_F(RttStatsTest,SmoothedRttStability)57 TEST_F(RttStatsTest, SmoothedRttStability) {
58   for (size_t time = 3; time < 20000; time++) {
59     RttStats stats;
60     for (size_t i = 0; i < 100; i++) {
61       stats.UpdateRtt(QuicTime::Delta::FromMicroseconds(time),
62                       QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
63       int64_t time_delta_us = stats.smoothed_rtt().ToMicroseconds() - time;
64       ASSERT_LE(std::abs(time_delta_us), 1);
65     }
66   }
67 }
68 
TEST_F(RttStatsTest,PreviousSmoothedRtt)69 TEST_F(RttStatsTest, PreviousSmoothedRtt) {
70   // Verify that ack_delay is corrected for in Smoothed RTT.
71   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
72                        QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
73   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
74   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
75   EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.previous_srtt());
76   // Ensure the previous SRTT is 200ms after a 100ms sample.
77   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
78                        QuicTime::Delta::Zero(), QuicTime::Zero());
79   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats_.latest_rtt());
80   EXPECT_EQ(QuicTime::Delta::FromMicroseconds(187500).ToMicroseconds(),
81             rtt_stats_.smoothed_rtt().ToMicroseconds());
82   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.previous_srtt());
83 }
84 
TEST_F(RttStatsTest,MinRtt)85 TEST_F(RttStatsTest, MinRtt) {
86   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
87                        QuicTime::Delta::Zero(), QuicTime::Zero());
88   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
89   rtt_stats_.UpdateRtt(
90       QuicTime::Delta::FromMilliseconds(10), QuicTime::Delta::Zero(),
91       QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(10));
92   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
93   rtt_stats_.UpdateRtt(
94       QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
95       QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(20));
96   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
97   rtt_stats_.UpdateRtt(
98       QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
99       QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(30));
100   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
101   rtt_stats_.UpdateRtt(
102       QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
103       QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(40));
104   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
105   // Verify that ack_delay does not go into recording of min_rtt_.
106   rtt_stats_.UpdateRtt(
107       QuicTime::Delta::FromMilliseconds(7),
108       QuicTime::Delta::FromMilliseconds(2),
109       QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(50));
110   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(7), rtt_stats_.min_rtt());
111 }
112 
TEST_F(RttStatsTest,ExpireSmoothedMetrics)113 TEST_F(RttStatsTest, ExpireSmoothedMetrics) {
114   QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(10);
115   rtt_stats_.UpdateRtt(initial_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
116   EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
117   EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
118 
119   EXPECT_EQ(0.5 * initial_rtt, rtt_stats_.mean_deviation());
120 
121   // Update once with a 20ms RTT.
122   QuicTime::Delta doubled_rtt = 2 * initial_rtt;
123   rtt_stats_.UpdateRtt(doubled_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
124   EXPECT_EQ(1.125 * initial_rtt, rtt_stats_.smoothed_rtt());
125 
126   // Expire the smoothed metrics, increasing smoothed rtt and mean deviation.
127   rtt_stats_.ExpireSmoothedMetrics();
128   EXPECT_EQ(doubled_rtt, rtt_stats_.smoothed_rtt());
129   EXPECT_EQ(0.875 * initial_rtt, rtt_stats_.mean_deviation());
130 
131   // Now go back down to 5ms and expire the smoothed metrics, and ensure the
132   // mean deviation increases to 15ms.
133   QuicTime::Delta half_rtt = 0.5 * initial_rtt;
134   rtt_stats_.UpdateRtt(half_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
135   EXPECT_GT(doubled_rtt, rtt_stats_.smoothed_rtt());
136   EXPECT_LT(initial_rtt, rtt_stats_.mean_deviation());
137 }
138 
TEST_F(RttStatsTest,UpdateRttWithBadSendDeltas)139 TEST_F(RttStatsTest, UpdateRttWithBadSendDeltas) {
140   QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(10);
141   rtt_stats_.UpdateRtt(initial_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
142   EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
143   EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
144 
145   std::vector<QuicTime::Delta> bad_send_deltas;
146   bad_send_deltas.push_back(QuicTime::Delta::Zero());
147   bad_send_deltas.push_back(QuicTime::Delta::Infinite());
148   bad_send_deltas.push_back(QuicTime::Delta::FromMicroseconds(-1000));
149 
150   for (QuicTime::Delta bad_send_delta : bad_send_deltas) {
151     SCOPED_TRACE(Message() << "bad_send_delta = "
152                            << bad_send_delta.ToMicroseconds());
153     EXPECT_FALSE(rtt_stats_.UpdateRtt(bad_send_delta, QuicTime::Delta::Zero(),
154                                       QuicTime::Zero()));
155     EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
156     EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
157   }
158 }
159 
TEST_F(RttStatsTest,ResetAfterConnectionMigrations)160 TEST_F(RttStatsTest, ResetAfterConnectionMigrations) {
161   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
162                        QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
163   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
164   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
165   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
166 
167   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
168                        QuicTime::Delta::FromMilliseconds(100),
169                        QuicTime::Zero());
170   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
171   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
172   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
173 
174   // Reset rtt stats on connection migrations.
175   rtt_stats_.OnConnectionMigration();
176   EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.latest_rtt());
177   EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.smoothed_rtt());
178   EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.min_rtt());
179 }
180 
TEST_F(RttStatsTest,StandardDeviationCalculatorTest1)181 TEST_F(RttStatsTest, StandardDeviationCalculatorTest1) {
182   // All samples are the same.
183   rtt_stats_.EnableStandardDeviationCalculation();
184   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
185                        QuicTime::Delta::Zero(), QuicTime::Zero());
186   EXPECT_EQ(rtt_stats_.mean_deviation(),
187             rtt_stats_.GetStandardOrMeanDeviation());
188 
189   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
190                        QuicTime::Delta::Zero(), QuicTime::Zero());
191   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
192                        QuicTime::Delta::Zero(), QuicTime::Zero());
193   EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.GetStandardOrMeanDeviation());
194 }
195 
TEST_F(RttStatsTest,StandardDeviationCalculatorTest2)196 TEST_F(RttStatsTest, StandardDeviationCalculatorTest2) {
197   // Small variance.
198   rtt_stats_.EnableStandardDeviationCalculation();
199   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
200                        QuicTime::Delta::Zero(), QuicTime::Zero());
201   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
202                        QuicTime::Delta::Zero(), QuicTime::Zero());
203   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
204                        QuicTime::Delta::Zero(), QuicTime::Zero());
205   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(9),
206                        QuicTime::Delta::Zero(), QuicTime::Zero());
207   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(11),
208                        QuicTime::Delta::Zero(), QuicTime::Zero());
209   EXPECT_LT(QuicTime::Delta::FromMicroseconds(500),
210             rtt_stats_.GetStandardOrMeanDeviation());
211   EXPECT_GT(QuicTime::Delta::FromMilliseconds(1),
212             rtt_stats_.GetStandardOrMeanDeviation());
213 }
214 
TEST_F(RttStatsTest,StandardDeviationCalculatorTest3)215 TEST_F(RttStatsTest, StandardDeviationCalculatorTest3) {
216   // Some variance.
217   rtt_stats_.EnableStandardDeviationCalculation();
218   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
219                        QuicTime::Delta::Zero(), QuicTime::Zero());
220   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
221                        QuicTime::Delta::Zero(), QuicTime::Zero());
222   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
223                        QuicTime::Delta::Zero(), QuicTime::Zero());
224   rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
225                        QuicTime::Delta::Zero(), QuicTime::Zero());
226   EXPECT_APPROX_EQ(rtt_stats_.mean_deviation(),
227                    rtt_stats_.GetStandardOrMeanDeviation(), 0.25f);
228 }
229 
230 }  // namespace test
231 }  // namespace quic
232