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