blob: 8059ff6a967969f21a8f87b2f5dbf85fecd10fe3 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2017 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_control_frame_manager.h"
6
fayang83d7e3e2019-07-31 14:45:19 -07007#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05008#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
9#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
10#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
11#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
12
13using testing::_;
14using testing::InSequence;
bnc5b3c3be2019-06-25 10:37:09 -070015using testing::Invoke;
QUICHE teama6ef0a62019-03-07 20:34:33 -050016using testing::Return;
17using testing::StrictMock;
18
19namespace quic {
20namespace test {
21
22class QuicControlFrameManagerPeer {
23 public:
24 static size_t QueueSize(QuicControlFrameManager* manager) {
25 return manager->control_frames_.size();
26 }
27};
28
29namespace {
30
31const QuicStreamId kTestStreamId = 5;
32const QuicStreamId kTestStopSendingCode = 321;
33
34class QuicControlFrameManagerTest : public QuicTest {
35 public:
QUICHE teama6ef0a62019-03-07 20:34:33 -050036 bool SaveControlFrame(const QuicFrame& frame) {
37 frame_ = frame;
38 return true;
39 }
40
41 protected:
42 // Pre-fills the control frame queue with the following frames:
43 // ID Type
44 // 1 RST_STREAM
45 // 2 GO_AWAY
46 // 3 WINDOW_UPDATE
47 // 4 BLOCKED
48 // 5 STOP_SENDING
49 // This is verified. The tests then perform manipulations on these.
50 void Initialize() {
51 connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
52 Perspective::IS_SERVER);
53 session_ = QuicMakeUnique<StrictMock<MockQuicSession>>(connection_);
54 manager_ = QuicMakeUnique<QuicControlFrameManager>(session_.get());
55 EXPECT_EQ(0u, QuicControlFrameManagerPeer::QueueSize(manager_.get()));
56 EXPECT_FALSE(manager_->HasPendingRetransmission());
57 EXPECT_FALSE(manager_->WillingToWrite());
58
59 EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
60 manager_->WriteOrBufferRstStream(kTestStreamId, QUIC_STREAM_CANCELLED, 0);
61 manager_->WriteOrBufferGoAway(QUIC_PEER_GOING_AWAY, kTestStreamId,
62 "Going away.");
63 manager_->WriteOrBufferWindowUpdate(kTestStreamId, 100);
64 manager_->WriteOrBufferBlocked(kTestStreamId);
65 manager_->WriteOrBufferStopSending(kTestStopSendingCode, kTestStreamId);
66 number_of_frames_ = 5u;
67 ping_frame_id_ = 6u;
68 EXPECT_EQ(number_of_frames_,
69 QuicControlFrameManagerPeer::QueueSize(manager_.get()));
70 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
71 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
72 EXPECT_TRUE(
73 manager_->IsControlFrameOutstanding(QuicFrame(&window_update_)));
74 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&blocked_)));
75 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&stop_sending_)));
76 EXPECT_FALSE(manager_->IsControlFrameOutstanding(
77 QuicFrame(QuicPingFrame(ping_frame_id_))));
78
79 EXPECT_FALSE(manager_->HasPendingRetransmission());
80 EXPECT_TRUE(manager_->WillingToWrite());
81 }
82
83 QuicRstStreamFrame rst_stream_ = {1, kTestStreamId, QUIC_STREAM_CANCELLED, 0};
84 QuicGoAwayFrame goaway_ = {2, QUIC_PEER_GOING_AWAY, kTestStreamId,
85 "Going away."};
86 QuicWindowUpdateFrame window_update_ = {3, kTestStreamId, 100};
87 QuicBlockedFrame blocked_ = {4, kTestStreamId};
88 QuicStopSendingFrame stop_sending_ = {5, kTestStreamId, kTestStopSendingCode};
89 MockQuicConnectionHelper helper_;
90 MockAlarmFactory alarm_factory_;
91 MockQuicConnection* connection_;
92 std::unique_ptr<StrictMock<MockQuicSession>> session_;
93 std::unique_ptr<QuicControlFrameManager> manager_;
94 QuicFrame frame_;
95 size_t number_of_frames_;
96 int ping_frame_id_;
97};
98
99TEST_F(QuicControlFrameManagerTest, OnControlFrameAcked) {
100 Initialize();
101 InSequence s;
102 EXPECT_CALL(*connection_, SendControlFrame(_))
103 .Times(3)
bnc5b3c3be2019-06-25 10:37:09 -0700104 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500105 EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
106 // Send control frames 1, 2, 3.
107 manager_->OnCanWrite();
108 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
109 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
110 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&window_update_)));
111 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&blocked_)));
112 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&stop_sending_)));
113
114 EXPECT_FALSE(manager_->IsControlFrameOutstanding(
115 QuicFrame(QuicPingFrame(ping_frame_id_))));
116 EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&window_update_)));
117 EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&window_update_)));
118 EXPECT_EQ(number_of_frames_,
119 QuicControlFrameManagerPeer::QueueSize(manager_.get()));
120
121 EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&goaway_)));
122 EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
123 EXPECT_EQ(number_of_frames_,
124 QuicControlFrameManagerPeer::QueueSize(manager_.get()));
125 EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&rst_stream_)));
126 EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
127 // Only after the first frame in the queue is acked do the frames get
128 // removed ... now see that the length has been reduced by 3.
129 EXPECT_EQ(number_of_frames_ - 3u,
130 QuicControlFrameManagerPeer::QueueSize(manager_.get()));
131 // Duplicate ack.
132 EXPECT_FALSE(manager_->OnControlFrameAcked(QuicFrame(&goaway_)));
133
134 EXPECT_FALSE(manager_->HasPendingRetransmission());
135 EXPECT_TRUE(manager_->WillingToWrite());
136
137 // Send control frames 4, 5.
138 EXPECT_CALL(*connection_, SendControlFrame(_))
bnc5b3c3be2019-06-25 10:37:09 -0700139 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500140 manager_->OnCanWrite();
141 manager_->WritePing();
142 EXPECT_FALSE(manager_->WillingToWrite());
143}
144
145TEST_F(QuicControlFrameManagerTest, OnControlFrameLost) {
146 Initialize();
147 InSequence s;
148 EXPECT_CALL(*connection_, SendControlFrame(_))
149 .Times(3)
bnc5b3c3be2019-06-25 10:37:09 -0700150 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500151 EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
152 // Send control frames 1, 2, 3.
153 manager_->OnCanWrite();
154
155 // Lost control frames 1, 2, 3.
156 manager_->OnControlFrameLost(QuicFrame(&rst_stream_));
157 manager_->OnControlFrameLost(QuicFrame(&goaway_));
158 manager_->OnControlFrameLost(QuicFrame(&window_update_));
159 EXPECT_TRUE(manager_->HasPendingRetransmission());
160
161 // Ack control frame 2.
162 manager_->OnControlFrameAcked(QuicFrame(&goaway_));
163
164 // Retransmit control frames 1, 3.
165 EXPECT_CALL(*connection_, SendControlFrame(_))
166 .Times(2)
bnc5b3c3be2019-06-25 10:37:09 -0700167 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500168 manager_->OnCanWrite();
169 EXPECT_FALSE(manager_->HasPendingRetransmission());
170 EXPECT_TRUE(manager_->WillingToWrite());
171
172 // Send control frames 4, 5, and 6.
173 EXPECT_CALL(*connection_, SendControlFrame(_))
174 .Times(number_of_frames_ - 2u)
bnc5b3c3be2019-06-25 10:37:09 -0700175 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500176 manager_->OnCanWrite();
177 manager_->WritePing();
178 EXPECT_FALSE(manager_->WillingToWrite());
179}
180
181TEST_F(QuicControlFrameManagerTest, RetransmitControlFrame) {
182 Initialize();
183 InSequence s;
184 // Send control frames 1, 2, 3, 4.
185 EXPECT_CALL(*connection_, SendControlFrame(_))
186 .Times(number_of_frames_)
bnc5b3c3be2019-06-25 10:37:09 -0700187 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500188 manager_->OnCanWrite();
189
190 // Ack control frame 2.
191 manager_->OnControlFrameAcked(QuicFrame(&goaway_));
192 // Do not retransmit an acked frame.
193 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
194 EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&goaway_)));
195
196 // Retransmit control frame 3.
197 EXPECT_CALL(*connection_, SendControlFrame(_))
bnc5b3c3be2019-06-25 10:37:09 -0700198 .WillOnce(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500199 EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&window_update_)));
200
201 // Retransmit control frame 4, and connection is write blocked.
202 EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
203 EXPECT_FALSE(manager_->RetransmitControlFrame(QuicFrame(&window_update_)));
204}
205
206TEST_F(QuicControlFrameManagerTest, DonotSendPingWithBufferedFrames) {
207 Initialize();
208 InSequence s;
209 EXPECT_CALL(*connection_, SendControlFrame(_))
bnc5b3c3be2019-06-25 10:37:09 -0700210 .WillOnce(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500211 EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
212 // Send control frame 1.
213 manager_->OnCanWrite();
214 EXPECT_FALSE(manager_->HasPendingRetransmission());
215 EXPECT_TRUE(manager_->WillingToWrite());
216
217 // Send PING when there is buffered frames.
218 manager_->WritePing();
219 // Verify only the buffered frames are sent.
220 EXPECT_CALL(*connection_, SendControlFrame(_))
221 .Times(number_of_frames_ - 1)
bnc5b3c3be2019-06-25 10:37:09 -0700222 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500223 manager_->OnCanWrite();
224 EXPECT_FALSE(manager_->HasPendingRetransmission());
225 EXPECT_FALSE(manager_->WillingToWrite());
226}
227
228TEST_F(QuicControlFrameManagerTest, DonotRetransmitOldWindowUpdates) {
229 Initialize();
230 // Send two more window updates of the same stream.
231 manager_->WriteOrBufferWindowUpdate(kTestStreamId, 200);
232 QuicWindowUpdateFrame window_update2(number_of_frames_ + 1, kTestStreamId,
233 200);
234
235 manager_->WriteOrBufferWindowUpdate(kTestStreamId, 300);
236 QuicWindowUpdateFrame window_update3(number_of_frames_ + 2, kTestStreamId,
237 300);
238 InSequence s;
239 // Flush all buffered control frames.
240 EXPECT_CALL(*connection_, SendControlFrame(_))
bnc5b3c3be2019-06-25 10:37:09 -0700241 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500242 manager_->OnCanWrite();
243
244 // Mark all 3 window updates as lost.
245 manager_->OnControlFrameLost(QuicFrame(&window_update_));
246 manager_->OnControlFrameLost(QuicFrame(&window_update2));
247 manager_->OnControlFrameLost(QuicFrame(&window_update3));
248 EXPECT_TRUE(manager_->HasPendingRetransmission());
249 EXPECT_TRUE(manager_->WillingToWrite());
250
251 // Verify only the latest window update gets retransmitted.
252 EXPECT_CALL(*connection_, SendControlFrame(_))
253 .WillOnce(Invoke(this, &QuicControlFrameManagerTest::SaveControlFrame));
254 manager_->OnCanWrite();
255 EXPECT_EQ(number_of_frames_ + 2u,
256 frame_.window_update_frame->control_frame_id);
257 EXPECT_FALSE(manager_->HasPendingRetransmission());
258 EXPECT_FALSE(manager_->WillingToWrite());
259 DeleteFrame(&frame_);
260}
261
262TEST_F(QuicControlFrameManagerTest, RetransmitWindowUpdateOfDifferentStreams) {
263 Initialize();
264 // Send two more window updates of different streams.
265 manager_->WriteOrBufferWindowUpdate(kTestStreamId + 2, 200);
266 QuicWindowUpdateFrame window_update2(5, kTestStreamId + 2, 200);
267
268 manager_->WriteOrBufferWindowUpdate(kTestStreamId + 4, 300);
269 QuicWindowUpdateFrame window_update3(6, kTestStreamId + 4, 300);
270 InSequence s;
271 // Flush all buffered control frames.
272 EXPECT_CALL(*connection_, SendControlFrame(_))
bnc5b3c3be2019-06-25 10:37:09 -0700273 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500274 manager_->OnCanWrite();
275
276 // Mark all 3 window updates as lost.
277 manager_->OnControlFrameLost(QuicFrame(&window_update_));
278 manager_->OnControlFrameLost(QuicFrame(&window_update2));
279 manager_->OnControlFrameLost(QuicFrame(&window_update3));
280 EXPECT_TRUE(manager_->HasPendingRetransmission());
281 EXPECT_TRUE(manager_->WillingToWrite());
282
283 // Verify all 3 window updates get retransmitted.
284 EXPECT_CALL(*connection_, SendControlFrame(_))
285 .Times(3)
bnc5b3c3be2019-06-25 10:37:09 -0700286 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500287 manager_->OnCanWrite();
288 EXPECT_FALSE(manager_->HasPendingRetransmission());
289 EXPECT_FALSE(manager_->WillingToWrite());
290}
291
fayang83d7e3e2019-07-31 14:45:19 -0700292TEST_F(QuicControlFrameManagerTest, TooManyBufferedControlFrames) {
293 SetQuicReloadableFlag(quic_add_upper_limit_of_buffered_control_frames, true);
294 Initialize();
295 EXPECT_CALL(*connection_, SendControlFrame(_))
296 .Times(5)
297 .WillRepeatedly(Invoke(&ClearControlFrame));
298 // Flush buffered frames.
299 manager_->OnCanWrite();
300 // Write 995 control frames.
301 EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
302 for (size_t i = 0; i < 995; ++i) {
303 manager_->WriteOrBufferRstStream(kTestStreamId, QUIC_STREAM_CANCELLED, 0);
304 }
305 // Verify write one more control frame causes connection close.
306 EXPECT_CALL(
307 *connection_,
308 CloseConnection(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, _,
309 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
310 manager_->WriteOrBufferRstStream(kTestStreamId, QUIC_STREAM_CANCELLED, 0);
311}
312
QUICHE teama6ef0a62019-03-07 20:34:33 -0500313} // namespace
314} // namespace test
315} // namespace quic