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 "base/test/mock_log.h"
11 #include "net/quic/test_tools/rtt_stats_peer.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 using logging::LOG_WARNING
;
16 using testing::HasSubstr
;
17 using testing::Message
;
23 class RttStatsTest
: public ::testing::Test
{
28 TEST_F(RttStatsTest
, DefaultsBeforeUpdate
) {
29 EXPECT_LT(0u, rtt_stats_
.initial_rtt_us());
30 EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_
.min_rtt());
31 EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_
.smoothed_rtt());
34 TEST_F(RttStatsTest
, SmoothedRtt
) {
35 // Verify that ack_delay is corrected for in Smoothed RTT.
36 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
37 QuicTime::Delta::FromMilliseconds(100),
39 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.latest_rtt());
40 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.smoothed_rtt());
41 // Verify that effective RTT of zero does not change Smoothed RTT.
42 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
43 QuicTime::Delta::FromMilliseconds(200),
45 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.latest_rtt());
46 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.smoothed_rtt());
47 // Verify that large erroneous ack_delay does not change Smoothed RTT.
48 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
49 QuicTime::Delta::FromMilliseconds(300),
51 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.latest_rtt());
52 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.smoothed_rtt());
55 TEST_F(RttStatsTest
, MinRtt
) {
56 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
57 QuicTime::Delta::Zero(),
59 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_
.min_rtt());
60 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
61 rtt_stats_
.recent_min_rtt());
62 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
63 QuicTime::Delta::Zero(),
65 QuicTime::Delta::FromMilliseconds(10)));
66 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
67 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.recent_min_rtt());
68 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
69 QuicTime::Delta::Zero(),
71 QuicTime::Delta::FromMilliseconds(20)));
72 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
73 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.recent_min_rtt());
74 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
75 QuicTime::Delta::Zero(),
77 QuicTime::Delta::FromMilliseconds(30)));
78 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
79 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.recent_min_rtt());
80 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
81 QuicTime::Delta::Zero(),
83 QuicTime::Delta::FromMilliseconds(40)));
84 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
85 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.recent_min_rtt());
86 // Verify that ack_delay does not go into recording of min_rtt_.
87 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(7),
88 QuicTime::Delta::FromMilliseconds(2),
90 QuicTime::Delta::FromMilliseconds(50)));
91 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(7), rtt_stats_
.min_rtt());
92 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(7), rtt_stats_
.recent_min_rtt());
95 TEST_F(RttStatsTest
, RecentMinRtt
) {
96 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
97 QuicTime::Delta::Zero(),
99 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
100 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.recent_min_rtt());
102 rtt_stats_
.SampleNewRecentMinRtt(4);
103 for (int i
= 0; i
< 3; ++i
) {
104 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
105 QuicTime::Delta::Zero(),
107 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
108 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
109 rtt_stats_
.recent_min_rtt());
111 rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
112 QuicTime::Delta::Zero(),
114 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
115 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50), rtt_stats_
.recent_min_rtt());
118 TEST_F(RttStatsTest
, WindowedRecentMinRtt
) {
119 // Set the window to 99ms, so 25ms is more than a quarter rtt.
120 rtt_stats_
.set_recent_min_rtt_window(QuicTime::Delta::FromMilliseconds(99));
122 QuicTime now
= QuicTime::Zero();
123 QuicTime::Delta rtt_sample
= QuicTime::Delta::FromMilliseconds(10);
124 rtt_stats_
.UpdateRtt(rtt_sample
, QuicTime::Delta::Zero(), now
);
125 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
126 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.recent_min_rtt());
128 // Gradually increase the rtt samples and ensure the recent_min_rtt starts
130 for (int i
= 0; i
< 8; ++i
) {
131 now
= now
.Add(QuicTime::Delta::FromMilliseconds(25));
132 rtt_sample
= rtt_sample
.Add(QuicTime::Delta::FromMilliseconds(10));
133 rtt_stats_
.UpdateRtt(rtt_sample
, QuicTime::Delta::Zero(), now
);
134 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
135 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_
));
136 EXPECT_EQ(rtt_sample
.Subtract(QuicTime::Delta::FromMilliseconds(10)),
137 RttStatsPeer::GetHalfWindowRtt(&rtt_stats_
));
139 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
140 rtt_stats_
.recent_min_rtt());
142 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(30),
143 rtt_stats_
.recent_min_rtt());
145 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50),
146 rtt_stats_
.recent_min_rtt());
148 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70),
149 rtt_stats_
.recent_min_rtt());
153 // A new quarter rtt low sets that, but nothing else.
154 rtt_sample
= rtt_sample
.Subtract(QuicTime::Delta::FromMilliseconds(5));
155 rtt_stats_
.UpdateRtt(rtt_sample
, QuicTime::Delta::Zero(), now
);
156 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
157 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_
));
158 EXPECT_EQ(rtt_sample
.Subtract(QuicTime::Delta::FromMilliseconds(5)),
159 RttStatsPeer::GetHalfWindowRtt(&rtt_stats_
));
160 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70),
161 rtt_stats_
.recent_min_rtt());
163 // A new half rtt low sets that and the quarter rtt low.
164 rtt_sample
= rtt_sample
.Subtract(QuicTime::Delta::FromMilliseconds(15));
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
, RttStatsPeer::GetHalfWindowRtt(&rtt_stats_
));
169 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70),
170 rtt_stats_
.recent_min_rtt());
172 // A new full window loss sets the recent_min_rtt, but not min_rtt.
173 rtt_sample
= QuicTime::Delta::FromMilliseconds(65);
174 rtt_stats_
.UpdateRtt(rtt_sample
, QuicTime::Delta::Zero(), now
);
175 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_
.min_rtt());
176 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_
));
177 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetHalfWindowRtt(&rtt_stats_
));
178 EXPECT_EQ(rtt_sample
, rtt_stats_
.recent_min_rtt());
180 // A new all time low sets both the min_rtt and the recent_min_rtt.
181 rtt_sample
= QuicTime::Delta::FromMilliseconds(5);
182 rtt_stats_
.UpdateRtt(rtt_sample
, QuicTime::Delta::Zero(), now
);
184 EXPECT_EQ(rtt_sample
, rtt_stats_
.min_rtt());
185 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_
));
186 EXPECT_EQ(rtt_sample
, RttStatsPeer::GetHalfWindowRtt(&rtt_stats_
));
187 EXPECT_EQ(rtt_sample
, rtt_stats_
.recent_min_rtt());
190 TEST_F(RttStatsTest
, ExpireSmoothedMetrics
) {
191 QuicTime::Delta initial_rtt
= QuicTime::Delta::FromMilliseconds(10);
192 rtt_stats_
.UpdateRtt(initial_rtt
, QuicTime::Delta::Zero(), QuicTime::Zero());
193 EXPECT_EQ(initial_rtt
, rtt_stats_
.min_rtt());
194 EXPECT_EQ(initial_rtt
, rtt_stats_
.recent_min_rtt());
195 EXPECT_EQ(initial_rtt
, rtt_stats_
.smoothed_rtt());
197 EXPECT_EQ(initial_rtt
.Multiply(0.5), rtt_stats_
.mean_deviation());
199 // Update once with a 20ms RTT.
200 QuicTime::Delta doubled_rtt
= initial_rtt
.Multiply(2);
201 rtt_stats_
.UpdateRtt(doubled_rtt
, QuicTime::Delta::Zero(), QuicTime::Zero());
202 EXPECT_EQ(initial_rtt
.Multiply(1.125), rtt_stats_
.smoothed_rtt());
204 // Expire the smoothed metrics, increasing smoothed rtt and mean deviation.
205 rtt_stats_
.ExpireSmoothedMetrics();
206 EXPECT_EQ(doubled_rtt
, rtt_stats_
.smoothed_rtt());
207 EXPECT_EQ(initial_rtt
.Multiply(0.875), rtt_stats_
.mean_deviation());
209 // Now go back down to 5ms and expire the smoothed metrics, and ensure the
210 // mean deviation increases to 15ms.
211 QuicTime::Delta half_rtt
= initial_rtt
.Multiply(0.5);
212 rtt_stats_
.UpdateRtt(half_rtt
, QuicTime::Delta::Zero(), QuicTime::Zero());
213 EXPECT_GT(doubled_rtt
, rtt_stats_
.smoothed_rtt());
214 EXPECT_LT(initial_rtt
, rtt_stats_
.mean_deviation());
217 TEST_F(RttStatsTest
, UpdateRttWithBadSendDeltas
) {
218 // Make sure we ignore bad RTTs.
219 base::test::MockLog log
;
221 QuicTime::Delta initial_rtt
= QuicTime::Delta::FromMilliseconds(10);
222 rtt_stats_
.UpdateRtt(initial_rtt
, QuicTime::Delta::Zero(), QuicTime::Zero());
223 EXPECT_EQ(initial_rtt
, rtt_stats_
.min_rtt());
224 EXPECT_EQ(initial_rtt
, rtt_stats_
.recent_min_rtt());
225 EXPECT_EQ(initial_rtt
, rtt_stats_
.smoothed_rtt());
227 vector
<QuicTime::Delta
> bad_send_deltas
;
228 bad_send_deltas
.push_back(QuicTime::Delta::Zero());
229 bad_send_deltas
.push_back(QuicTime::Delta::Infinite());
230 bad_send_deltas
.push_back(QuicTime::Delta::FromMicroseconds(-1000));
231 log
.StartCapturingLogs();
233 for (QuicTime::Delta bad_send_delta
: bad_send_deltas
) {
234 SCOPED_TRACE(Message() << "bad_send_delta = "
235 << bad_send_delta
.ToMicroseconds());
236 EXPECT_CALL(log
, Log(LOG_WARNING
, _
, _
, _
, HasSubstr("Ignoring")));
237 rtt_stats_
.UpdateRtt(bad_send_delta
,
238 QuicTime::Delta::Zero(),
240 EXPECT_EQ(initial_rtt
, rtt_stats_
.min_rtt());
241 EXPECT_EQ(initial_rtt
, rtt_stats_
.recent_min_rtt());
242 EXPECT_EQ(initial_rtt
, rtt_stats_
.smoothed_rtt());