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