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