xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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