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