OLD | NEW |
| (Empty) |
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/quic/congestion_control/rtt_stats.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "base/logging.h" | |
10 #include "net/test/scoped_mock_log.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 | |
13 using logging::LOG_WARNING; | |
14 using std::vector; | |
15 using testing::HasSubstr; | |
16 using testing::Message; | |
17 using testing::_; | |
18 | |
19 namespace net { | |
20 namespace test { | |
21 | |
22 class RttStatsPeer { | |
23 public: | |
24 static QuicTime::Delta GetHalfWindowRtt(const RttStats* rtt_stats) { | |
25 return rtt_stats->half_window_rtt_.rtt; | |
26 } | |
27 | |
28 static QuicTime::Delta GetQuarterWindowRtt(const RttStats* rtt_stats) { | |
29 return rtt_stats->quarter_window_rtt_.rtt; | |
30 } | |
31 }; | |
32 | |
33 class RttStatsTest : public ::testing::Test { | |
34 protected: | |
35 RttStats rtt_stats_; | |
36 }; | |
37 | |
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()); | |
42 } | |
43 | |
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), | |
48 QuicTime::Zero()); | |
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), | |
54 QuicTime::Zero()); | |
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), | |
60 QuicTime::Zero()); | |
61 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt()); | |
62 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt()); | |
63 } | |
64 | |
65 TEST_F(RttStatsTest, MinRtt) { | |
66 rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200), | |
67 QuicTime::Delta::Zero(), | |
68 QuicTime::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(), | |
74 QuicTime::Zero().Add( | |
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(), | |
80 QuicTime::Zero().Add( | |
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(), | |
86 QuicTime::Zero().Add( | |
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(), | |
92 QuicTime::Zero().Add( | |
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), | |
99 QuicTime::Zero().Add( | |
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()); | |
103 } | |
104 | |
105 TEST_F(RttStatsTest, RecentMinRtt) { | |
106 rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10), | |
107 QuicTime::Delta::Zero(), | |
108 QuicTime::Zero()); | |
109 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); | |
110 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.recent_min_rtt()); | |
111 | |
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(), | |
116 QuicTime::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()); | |
120 } | |
121 rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50), | |
122 QuicTime::Delta::Zero(), | |
123 QuicTime::Zero()); | |
124 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); | |
125 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50), rtt_stats_.recent_min_rtt()); | |
126 } | |
127 | |
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)); | |
131 | |
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()); | |
137 | |
138 // Gradually increase the rtt samples and ensure the recent_min_rtt starts | |
139 // rising. | |
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_)); | |
148 if (i < 3) { | |
149 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), | |
150 rtt_stats_.recent_min_rtt()); | |
151 } else if (i < 5) { | |
152 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(30), | |
153 rtt_stats_.recent_min_rtt()); | |
154 } else if (i < 7) { | |
155 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50), | |
156 rtt_stats_.recent_min_rtt()); | |
157 } else { | |
158 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70), | |
159 rtt_stats_.recent_min_rtt()); | |
160 } | |
161 } | |
162 | |
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()); | |
172 | |
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()); | |
181 | |
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()); | |
189 | |
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); | |
193 | |
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()); | |
198 } | |
199 | |
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()); | |
206 | |
207 EXPECT_EQ(initial_rtt.Multiply(0.5), rtt_stats_.mean_deviation()); | |
208 | |
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()); | |
213 | |
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()); | |
218 | |
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()); | |
225 } | |
226 | |
227 TEST_F(RttStatsTest, UpdateRttWithBadSendDeltas) { | |
228 // Make sure we ignore bad RTTs. | |
229 ScopedMockLog log; | |
230 | |
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()); | |
236 | |
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(); | |
242 | |
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(), | |
249 QuicTime::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()); | |
253 } | |
254 } | |
255 | |
256 } // namespace test | |
257 } // namespace net | |
OLD | NEW |