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/quic_flow_controller.h" | |
6 | |
7 #include <memory> | |
8 | |
9 #include "base/format_macros.h" | |
10 #include "base/strings/stringprintf.h" | |
11 #include "net/quic/quic_flags.h" | |
12 #include "net/quic/quic_utils.h" | |
13 #include "net/quic/test_tools/quic_connection_peer.h" | |
14 #include "net/quic/test_tools/quic_flow_controller_peer.h" | |
15 #include "net/quic/test_tools/quic_sent_packet_manager_peer.h" | |
16 #include "net/quic/test_tools/quic_test_utils.h" | |
17 #include "net/test/gtest_util.h" | |
18 #include "testing/gmock/include/gmock/gmock.h" | |
19 | |
20 using testing::_; | |
21 | |
22 namespace net { | |
23 namespace test { | |
24 | |
25 // Receive window auto-tuning uses RTT in its logic. | |
26 const int64_t kRtt = 100; | |
27 | |
28 class QuicFlowControllerTest : public ::testing::Test { | |
29 public: | |
30 QuicFlowControllerTest() | |
31 : stream_id_(1234), | |
32 send_window_(kInitialSessionFlowControlWindowForTest), | |
33 receive_window_(kInitialSessionFlowControlWindowForTest), | |
34 connection_(&helper_, &alarm_factory_, Perspective::IS_CLIENT) {} | |
35 | |
36 void Initialize() { | |
37 flow_controller_.reset( | |
38 new QuicFlowController(&connection_, stream_id_, Perspective::IS_CLIENT, | |
39 send_window_, receive_window_, false)); | |
40 } | |
41 | |
42 protected: | |
43 QuicStreamId stream_id_; | |
44 QuicByteCount send_window_; | |
45 QuicByteCount receive_window_; | |
46 std::unique_ptr<QuicFlowController> flow_controller_; | |
47 MockQuicConnectionHelper helper_; | |
48 MockAlarmFactory alarm_factory_; | |
49 MockQuicConnection connection_; | |
50 }; | |
51 | |
52 TEST_F(QuicFlowControllerTest, SendingBytes) { | |
53 Initialize(); | |
54 | |
55 EXPECT_FALSE(flow_controller_->IsBlocked()); | |
56 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
57 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); | |
58 | |
59 // Send some bytes, but not enough to block. | |
60 flow_controller_->AddBytesSent(send_window_ / 2); | |
61 EXPECT_FALSE(flow_controller_->IsBlocked()); | |
62 EXPECT_EQ(send_window_ / 2, flow_controller_->SendWindowSize()); | |
63 | |
64 // Send enough bytes to block. | |
65 flow_controller_->AddBytesSent(send_window_ / 2); | |
66 EXPECT_TRUE(flow_controller_->IsBlocked()); | |
67 EXPECT_EQ(0u, flow_controller_->SendWindowSize()); | |
68 | |
69 // BLOCKED frame should get sent. | |
70 EXPECT_CALL(connection_, SendBlocked(stream_id_)).Times(1); | |
71 flow_controller_->MaybeSendBlocked(); | |
72 | |
73 // Update the send window, and verify this has unblocked. | |
74 EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_)); | |
75 EXPECT_FALSE(flow_controller_->IsBlocked()); | |
76 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); | |
77 | |
78 // Updating with a smaller offset doesn't change anything. | |
79 EXPECT_FALSE(flow_controller_->UpdateSendWindowOffset(send_window_ / 10)); | |
80 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); | |
81 | |
82 // Try to send more bytes, violating flow control. | |
83 EXPECT_CALL(connection_, | |
84 CloseConnection(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA, _, _)); | |
85 EXPECT_DFATAL(flow_controller_->AddBytesSent(send_window_ * 10), | |
86 base::StringPrintf("Trying to send an extra %" PRIu64 " bytes", | |
87 send_window_ * 10)); | |
88 EXPECT_TRUE(flow_controller_->IsBlocked()); | |
89 EXPECT_EQ(0u, flow_controller_->SendWindowSize()); | |
90 } | |
91 | |
92 TEST_F(QuicFlowControllerTest, ReceivingBytes) { | |
93 Initialize(); | |
94 | |
95 EXPECT_FALSE(flow_controller_->IsBlocked()); | |
96 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
97 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, | |
98 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
99 | |
100 // Receive some bytes, updating highest received offset, but not enough to | |
101 // fill flow control receive window. | |
102 EXPECT_TRUE( | |
103 flow_controller_->UpdateHighestReceivedOffset(1 + receive_window_ / 2)); | |
104 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
105 EXPECT_EQ((receive_window_ / 2) - 1, | |
106 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
107 | |
108 // Consume enough bytes to send a WINDOW_UPDATE frame. | |
109 EXPECT_CALL(connection_, SendWindowUpdate(stream_id_, ::testing::_)).Times(1); | |
110 | |
111 flow_controller_->AddBytesConsumed(1 + receive_window_ / 2); | |
112 | |
113 // Result is that once again we have a fully open receive window. | |
114 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
115 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, | |
116 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
117 } | |
118 | |
119 TEST_F(QuicFlowControllerTest, OnlySendBlockedFrameOncePerOffset) { | |
120 Initialize(); | |
121 | |
122 // Test that we don't send duplicate BLOCKED frames. We should only send one | |
123 // BLOCKED frame at a given send window offset. | |
124 EXPECT_FALSE(flow_controller_->IsBlocked()); | |
125 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
126 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); | |
127 | |
128 // Send enough bytes to block. | |
129 flow_controller_->AddBytesSent(send_window_); | |
130 EXPECT_TRUE(flow_controller_->IsBlocked()); | |
131 EXPECT_EQ(0u, flow_controller_->SendWindowSize()); | |
132 | |
133 // Expect that 2 BLOCKED frames should get sent in total. | |
134 EXPECT_CALL(connection_, SendBlocked(stream_id_)).Times(2); | |
135 | |
136 // BLOCKED frame should get sent. | |
137 flow_controller_->MaybeSendBlocked(); | |
138 | |
139 // BLOCKED frame should not get sent again until our send offset changes. | |
140 flow_controller_->MaybeSendBlocked(); | |
141 flow_controller_->MaybeSendBlocked(); | |
142 flow_controller_->MaybeSendBlocked(); | |
143 flow_controller_->MaybeSendBlocked(); | |
144 flow_controller_->MaybeSendBlocked(); | |
145 | |
146 // Update the send window, then send enough bytes to block again. | |
147 EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_)); | |
148 EXPECT_FALSE(flow_controller_->IsBlocked()); | |
149 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); | |
150 flow_controller_->AddBytesSent(send_window_); | |
151 EXPECT_TRUE(flow_controller_->IsBlocked()); | |
152 EXPECT_EQ(0u, flow_controller_->SendWindowSize()); | |
153 | |
154 // BLOCKED frame should get sent as send offset has changed. | |
155 flow_controller_->MaybeSendBlocked(); | |
156 } | |
157 | |
158 TEST_F(QuicFlowControllerTest, ReceivingBytesFastIncreasesFlowWindow) { | |
159 // This test will generate two WINDOW_UPDATE frames. | |
160 EXPECT_CALL(connection_, SendWindowUpdate(stream_id_, ::testing::_)).Times(2); | |
161 | |
162 Initialize(); | |
163 flow_controller_->set_auto_tune_receive_window(true); | |
164 | |
165 // Make sure clock is inititialized. | |
166 connection_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); | |
167 | |
168 QuicSentPacketManagerInterface* manager = | |
169 QuicConnectionPeer::GetSentPacketManager(&connection_, kDefaultPathId); | |
170 | |
171 RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats()); | |
172 rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt), | |
173 QuicTime::Delta::Zero(), QuicTime::Zero()); | |
174 | |
175 EXPECT_FALSE(flow_controller_->IsBlocked()); | |
176 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
177 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, | |
178 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
179 | |
180 QuicByteCount threshold = | |
181 QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get()); | |
182 | |
183 QuicStreamOffset receive_offset = threshold + 1; | |
184 // Receive some bytes, updating highest received offset, but not enough to | |
185 // fill flow control receive window. | |
186 EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset)); | |
187 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
188 EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset, | |
189 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
190 | |
191 // Consume enough bytes to send a WINDOW_UPDATE frame. | |
192 flow_controller_->AddBytesConsumed(threshold + 1); | |
193 // Result is that once again we have a fully open receive window. | |
194 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
195 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, | |
196 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
197 | |
198 // Move time forward, but by less than two RTTs. Then receive and consume | |
199 // some more, forcing a second WINDOW_UPDATE with an increased max window | |
200 // size. | |
201 connection_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt - 1)); | |
202 receive_offset += threshold + 1; | |
203 EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset)); | |
204 flow_controller_->AddBytesConsumed(threshold + 1); | |
205 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
206 QuicByteCount new_threshold = | |
207 QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get()); | |
208 EXPECT_GT(new_threshold, threshold); | |
209 } | |
210 | |
211 TEST_F(QuicFlowControllerTest, ReceivingBytesFastNoAutoTune) { | |
212 // This test will generate two WINDOW_UPDATE frames. | |
213 EXPECT_CALL(connection_, SendWindowUpdate(stream_id_, ::testing::_)).Times(2); | |
214 | |
215 Initialize(); | |
216 flow_controller_->set_auto_tune_receive_window(false); | |
217 | |
218 // Make sure clock is inititialized. | |
219 connection_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); | |
220 | |
221 QuicSentPacketManagerInterface* manager = | |
222 QuicConnectionPeer::GetSentPacketManager(&connection_, kDefaultPathId); | |
223 | |
224 RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats()); | |
225 rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt), | |
226 QuicTime::Delta::Zero(), QuicTime::Zero()); | |
227 | |
228 EXPECT_FALSE(flow_controller_->IsBlocked()); | |
229 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
230 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, | |
231 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
232 | |
233 QuicByteCount threshold = | |
234 QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get()); | |
235 | |
236 QuicStreamOffset receive_offset = threshold + 1; | |
237 // Receive some bytes, updating highest received offset, but not enough to | |
238 // fill flow control receive window. | |
239 EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset)); | |
240 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
241 EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset, | |
242 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
243 | |
244 // Consume enough bytes to send a WINDOW_UPDATE frame. | |
245 flow_controller_->AddBytesConsumed(threshold + 1); | |
246 // Result is that once again we have a fully open receive window. | |
247 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
248 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, | |
249 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
250 | |
251 // Move time forward, but by less than two RTTs. Then receive and consume | |
252 // some more, forcing a second WINDOW_UPDATE with an increased max window | |
253 // size. | |
254 connection_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt - 1)); | |
255 receive_offset += threshold + 1; | |
256 EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset)); | |
257 flow_controller_->AddBytesConsumed(threshold + 1); | |
258 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
259 QuicByteCount new_threshold = | |
260 QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get()); | |
261 EXPECT_EQ(new_threshold, threshold); | |
262 } | |
263 | |
264 TEST_F(QuicFlowControllerTest, ReceivingBytesNormalStableFlowWindow) { | |
265 // This test will generate two WINDOW_UPDATE frames. | |
266 EXPECT_CALL(connection_, SendWindowUpdate(stream_id_, ::testing::_)).Times(2); | |
267 | |
268 Initialize(); | |
269 flow_controller_->set_auto_tune_receive_window(true); | |
270 | |
271 // Make sure clock is inititialized. | |
272 connection_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); | |
273 | |
274 QuicSentPacketManagerInterface* manager = | |
275 QuicConnectionPeer::GetSentPacketManager(&connection_, kDefaultPathId); | |
276 RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats()); | |
277 rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt), | |
278 QuicTime::Delta::Zero(), QuicTime::Zero()); | |
279 | |
280 EXPECT_FALSE(flow_controller_->IsBlocked()); | |
281 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
282 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, | |
283 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
284 | |
285 QuicByteCount threshold = | |
286 QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get()); | |
287 | |
288 QuicStreamOffset receive_offset = threshold + 1; | |
289 // Receive some bytes, updating highest received offset, but not enough to | |
290 // fill flow control receive window. | |
291 EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset)); | |
292 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
293 EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset, | |
294 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
295 | |
296 flow_controller_->AddBytesConsumed(threshold + 1); | |
297 | |
298 // Result is that once again we have a fully open receive window. | |
299 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
300 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, | |
301 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
302 | |
303 // Move time forward, but by more than two RTTs. Then receive and consume | |
304 // some more, forcing a second WINDOW_UPDATE with unchanged max window size. | |
305 connection_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt + 1)); | |
306 | |
307 receive_offset += threshold + 1; | |
308 EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset)); | |
309 | |
310 flow_controller_->AddBytesConsumed(threshold + 1); | |
311 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
312 | |
313 QuicByteCount new_threshold = | |
314 QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get()); | |
315 | |
316 EXPECT_EQ(new_threshold, threshold); | |
317 } | |
318 | |
319 TEST_F(QuicFlowControllerTest, ReceivingBytesNormalNoAutoTune) { | |
320 // This test will generate two WINDOW_UPDATE frames. | |
321 EXPECT_CALL(connection_, SendWindowUpdate(stream_id_, ::testing::_)).Times(2); | |
322 | |
323 Initialize(); | |
324 flow_controller_->set_auto_tune_receive_window(false); | |
325 | |
326 // Make sure clock is inititialized. | |
327 connection_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); | |
328 | |
329 QuicSentPacketManagerInterface* manager = | |
330 QuicConnectionPeer::GetSentPacketManager(&connection_, kDefaultPathId); | |
331 RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats()); | |
332 rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt), | |
333 QuicTime::Delta::Zero(), QuicTime::Zero()); | |
334 | |
335 EXPECT_FALSE(flow_controller_->IsBlocked()); | |
336 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
337 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, | |
338 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
339 | |
340 QuicByteCount threshold = | |
341 QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get()); | |
342 | |
343 QuicStreamOffset receive_offset = threshold + 1; | |
344 // Receive some bytes, updating highest received offset, but not enough to | |
345 // fill flow control receive window. | |
346 EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset)); | |
347 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
348 EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset, | |
349 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
350 | |
351 flow_controller_->AddBytesConsumed(threshold + 1); | |
352 | |
353 // Result is that once again we have a fully open receive window. | |
354 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
355 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, | |
356 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); | |
357 | |
358 // Move time forward, but by more than two RTTs. Then receive and consume | |
359 // some more, forcing a second WINDOW_UPDATE with unchanged max window size. | |
360 connection_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt + 1)); | |
361 | |
362 receive_offset += threshold + 1; | |
363 EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset)); | |
364 | |
365 flow_controller_->AddBytesConsumed(threshold + 1); | |
366 EXPECT_FALSE(flow_controller_->FlowControlViolation()); | |
367 | |
368 QuicByteCount new_threshold = | |
369 QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get()); | |
370 | |
371 EXPECT_EQ(new_threshold, threshold); | |
372 } | |
373 | |
374 } // namespace test | |
375 } // namespace net | |
OLD | NEW |