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