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