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.
5 #include "net/quic/congestion_control/rtt_stats.h"
9 #include "base/logging.h"
10 #include "net/test/scoped_mock_log.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 using logging::LOG_WARNING
;
15 using testing::HasSubstr
;
16 using testing::Message
;
24 static QuicTime::Delta
GetHalfWindowRtt(const RttStats
* rtt_stats
) {
25 return rtt_stats
->half_window_rtt_
.rtt
;
28 static QuicTime::Delta
GetQuarterWindowRtt(const RttStats
* rtt_stats
) {
29 return rtt_stats
->quarter_window_rtt_
.rtt
;
33 class RttStatsTest
: public ::testing::Test
{
38 TEST_F(RttStatsTest
, DefaultsBeforeUpdate
) {
39 EXPECT_LT(0u, rtt_stats_
.initial_rtt_us());
40 EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_
.min_rtt());
41 EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_
.smoothed_rtt());
44 TEST_F(RttStatsTest
, SmoothedRtt
) {
45 // Verify that ack_delay is corrected for in Smoothed RTT.
46 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
47 QuicTime::Delta::FromMilliseconds(100),
49 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.latest_rtt());
50 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.smoothed_rtt());
51 // Verify that effective RTT of zero does not change Smoothed RTT.
52 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
53 QuicTime::Delta::FromMilliseconds(200),
55 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.latest_rtt());
56 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.smoothed_rtt());
57 // Verify that large erroneous ack_delay does not change Smoothed RTT.
58 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
59 QuicTime::Delta::FromMilliseconds(300),
61 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.latest_rtt());
62 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.smoothed_rtt());
65 TEST_F(RttStatsTest
, MinRtt
) {
66 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
67 QuicTime::Delta::Zero(),
69 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.min_rtt());
70 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
71 rtt_stats_
.recent_min_rtt());
72 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
73 QuicTime::Delta::Zero(),
75 QuicTime::Delta::FromMilliseconds(10)));
76 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
77 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.recent_min_rtt());
78 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
79 QuicTime::Delta::Zero(),
81 QuicTime::Delta::FromMilliseconds(20)));
82 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
83 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.recent_min_rtt());
84 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
85 QuicTime::Delta::Zero(),
87 QuicTime::Delta::FromMilliseconds(30)));
88 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
89 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.recent_min_rtt());
90 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
91 QuicTime::Delta::Zero(),
93 QuicTime::Delta::FromMilliseconds(40)));
94 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
95 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.recent_min_rtt());
96 // Verify that ack_delay does not go into recording of min_rtt_.
97 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(7),
98 QuicTime::Delta::FromMilliseconds(2),
100 QuicTime::Delta::FromMilliseconds(50)));
101 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(7), rtt_stats_
.min_rtt());
102 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(7), rtt_stats_
.recent_min_rtt());
105 TEST_F(RttStatsTest
, RecentMinRtt
) {
106 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
107 QuicTime::Delta::Zero(),
109 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
110 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.recent_min_rtt());
112 rtt_stats_
.SampleNewRecentMinRtt(4);
113 for (int i
= 0; i
< 3; ++i
) {
114 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
115 QuicTime::Delta::Zero(),
117 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
118 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
119 rtt_stats_
.recent_min_rtt());
121 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
122 QuicTime::Delta::Zero(),
124 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
125 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50), rtt_stats_
.recent_min_rtt());
128 TEST_F(RttStatsTest
, WindowedRecentMinRtt
) {
129 // Set the window to 99ms, so 25ms is more than a quarter rtt.
130 rtt_stats_
.set_recent_min_rtt_window(QuicTime::Delta::FromMilliseconds(99));
132 QuicTime now
= QuicTime::Zero();
133 QuicTime::Delta rtt_sample
= QuicTime::Delta::FromMilliseconds(10);
134 rtt_stats_
.UpdateRtt(rtt_sample
, QuicTime::Delta::Zero(), now
);
135 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
136 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.recent_min_rtt());
138 // Gradually increase the rtt samples and ensure the recent_min_rtt starts
140 for (int i
= 0; i
< 8; ++i
) {
141 now
= now
.Add(QuicTime::Delta::FromMilliseconds(25));
142 rtt_sample
= rtt_sample
.Add(QuicTime::Delta::FromMilliseconds(10));
143 rtt_stats_
.UpdateRtt(rtt_sample
, QuicTime::Delta::Zero(), now
);
144 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
145 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_
));
146 EXPECT_EQ(rtt_sample
.Subtract(QuicTime::Delta::FromMilliseconds(10)),
147 RttStatsPeer::GetHalfWindowRtt(&rtt_stats_
));
149 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
150 rtt_stats_
.recent_min_rtt());
152 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(30),
153 rtt_stats_
.recent_min_rtt());
155 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50),
156 rtt_stats_
.recent_min_rtt());
158 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70),
159 rtt_stats_
.recent_min_rtt());
163 // A new quarter rtt low sets that, but nothing else.
164 rtt_sample
= rtt_sample
.Subtract(QuicTime::Delta::FromMilliseconds(5));
165 rtt_stats_
.UpdateRtt(rtt_sample
, QuicTime::Delta::Zero(), now
);
166 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
167 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_
));
168 EXPECT_EQ(rtt_sample
.Subtract(QuicTime::Delta::FromMilliseconds(5)),
169 RttStatsPeer::GetHalfWindowRtt(&rtt_stats_
));
170 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70),
171 rtt_stats_
.recent_min_rtt());
173 // A new half rtt low sets that and the quarter rtt low.
174 rtt_sample
= rtt_sample
.Subtract(QuicTime::Delta::FromMilliseconds(15));
175 rtt_stats_
.UpdateRtt(rtt_sample
, QuicTime::Delta::Zero(), now
);
176 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
177 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_
));
178 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetHalfWindowRtt(&rtt_stats_
));
179 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70),
180 rtt_stats_
.recent_min_rtt());
182 // A new full window loss sets the recent_min_rtt, but not min_rtt.
183 rtt_sample
= QuicTime::Delta::FromMilliseconds(65);
184 rtt_stats_
.UpdateRtt(rtt_sample
, QuicTime::Delta::Zero(), now
);
185 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
186 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_
));
187 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetHalfWindowRtt(&rtt_stats_
));
188 EXPECT_EQ(rtt_sample
, rtt_stats_
.recent_min_rtt());
190 // A new all time low sets both the min_rtt and the recent_min_rtt.
191 rtt_sample
= QuicTime::Delta::FromMilliseconds(5);
192 rtt_stats_
.UpdateRtt(rtt_sample
, QuicTime::Delta::Zero(), now
);
194 EXPECT_EQ(rtt_sample
, rtt_stats_
.min_rtt());
195 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_
));
196 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetHalfWindowRtt(&rtt_stats_
));
197 EXPECT_EQ(rtt_sample
, rtt_stats_
.recent_min_rtt());
200 TEST_F(RttStatsTest
, ExpireSmoothedMetrics
) {
201 QuicTime::Delta initial_rtt
= QuicTime::Delta::FromMilliseconds(10);
202 rtt_stats_
.UpdateRtt(initial_rtt
, QuicTime::Delta::Zero(), QuicTime::Zero());
203 EXPECT_EQ(initial_rtt
, rtt_stats_
.min_rtt());
204 EXPECT_EQ(initial_rtt
, rtt_stats_
.recent_min_rtt());
205 EXPECT_EQ(initial_rtt
, rtt_stats_
.smoothed_rtt());
207 EXPECT_EQ(initial_rtt
.Multiply(0.5), rtt_stats_
.mean_deviation());
209 // Update once with a 20ms RTT.
210 QuicTime::Delta doubled_rtt
= initial_rtt
.Multiply(2);
211 rtt_stats_
.UpdateRtt(doubled_rtt
, QuicTime::Delta::Zero(), QuicTime::Zero());
212 EXPECT_EQ(initial_rtt
.Multiply(1.125), rtt_stats_
.smoothed_rtt());
214 // Expire the smoothed metrics, increasing smoothed rtt and mean deviation.
215 rtt_stats_
.ExpireSmoothedMetrics();
216 EXPECT_EQ(doubled_rtt
, rtt_stats_
.smoothed_rtt());
217 EXPECT_EQ(initial_rtt
.Multiply(0.875), rtt_stats_
.mean_deviation());
219 // Now go back down to 5ms and expire the smoothed metrics, and ensure the
220 // mean deviation increases to 15ms.
221 QuicTime::Delta half_rtt
= initial_rtt
.Multiply(0.5);
222 rtt_stats_
.UpdateRtt(half_rtt
, QuicTime::Delta::Zero(), QuicTime::Zero());
223 EXPECT_GT(doubled_rtt
, rtt_stats_
.smoothed_rtt());
224 EXPECT_LT(initial_rtt
, rtt_stats_
.mean_deviation());
227 TEST_F(RttStatsTest
, UpdateRttWithBadSendDeltas
) {
228 // Make sure we ignore bad RTTs.
231 QuicTime::Delta initial_rtt
= QuicTime::Delta::FromMilliseconds(10);
232 rtt_stats_
.UpdateRtt(initial_rtt
, QuicTime::Delta::Zero(), QuicTime::Zero());
233 EXPECT_EQ(initial_rtt
, rtt_stats_
.min_rtt());
234 EXPECT_EQ(initial_rtt
, rtt_stats_
.recent_min_rtt());
235 EXPECT_EQ(initial_rtt
, rtt_stats_
.smoothed_rtt());
237 vector
<QuicTime::Delta
> bad_send_deltas
;
238 bad_send_deltas
.push_back(QuicTime::Delta::Zero());
239 bad_send_deltas
.push_back(QuicTime::Delta::Infinite());
240 bad_send_deltas
.push_back(QuicTime::Delta::FromMicroseconds(-1000));
241 log
.StartCapturingLogs();
243 for (QuicTime::Delta bad_send_delta
: bad_send_deltas
) {
244 SCOPED_TRACE(Message() << "bad_send_delta = "
245 << bad_send_delta
.ToMicroseconds());
246 EXPECT_CALL(log
, Log(LOG_WARNING
, _
, _
, _
, HasSubstr("Ignoring")));
247 rtt_stats_
.UpdateRtt(bad_send_delta
,
248 QuicTime::Delta::Zero(),
250 EXPECT_EQ(initial_rtt
, rtt_stats_
.min_rtt());
251 EXPECT_EQ(initial_rtt
, rtt_stats_
.recent_min_rtt());
252 EXPECT_EQ(initial_rtt
, rtt_stats_
.smoothed_rtt());