blob: e76e09ffb9a31c383b65a8105e466dc83a9043e2 [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
bnc463f2352019-10-10 04:49:34 -07007#include <utility>
8
fayang83d7e3e2019-07-31 14:45:19 -07009#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
12#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
13
14using testing::_;
15using testing::InSequence;
bnc5b3c3be2019-06-25 10:37:09 -070016using testing::Invoke;
QUICHE teama6ef0a62019-03-07 20:34:33 -050017using testing::Return;
18using testing::StrictMock;
19
20namespace quic {
21namespace test {
22
23class QuicControlFrameManagerPeer {
24 public:
25 static size_t QueueSize(QuicControlFrameManager* manager) {
26 return manager->control_frames_.size();
27 }
28};
29
30namespace {
31
32const QuicStreamId kTestStreamId = 5;
33const QuicStreamId kTestStopSendingCode = 321;
34
35class QuicControlFrameManagerTest : public QuicTest {
36 public:
QUICHE teama6ef0a62019-03-07 20:34:33 -050037 bool SaveControlFrame(const QuicFrame& frame) {
38 frame_ = frame;
39 return true;
40 }
41
42 protected:
43 // Pre-fills the control frame queue with the following frames:
44 // ID Type
45 // 1 RST_STREAM
46 // 2 GO_AWAY
47 // 3 WINDOW_UPDATE
48 // 4 BLOCKED
49 // 5 STOP_SENDING
50 // This is verified. The tests then perform manipulations on these.
51 void Initialize() {
52 connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
53 Perspective::IS_SERVER);
vasilvv0fc587f2019-09-06 13:33:08 -070054 session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_);
55 manager_ = std::make_unique<QuicControlFrameManager>(session_.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -050056 EXPECT_EQ(0u, QuicControlFrameManagerPeer::QueueSize(manager_.get()));
57 EXPECT_FALSE(manager_->HasPendingRetransmission());
58 EXPECT_FALSE(manager_->WillingToWrite());
59
60 EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
61 manager_->WriteOrBufferRstStream(kTestStreamId, QUIC_STREAM_CANCELLED, 0);
62 manager_->WriteOrBufferGoAway(QUIC_PEER_GOING_AWAY, kTestStreamId,
63 "Going away.");
64 manager_->WriteOrBufferWindowUpdate(kTestStreamId, 100);
65 manager_->WriteOrBufferBlocked(kTestStreamId);
66 manager_->WriteOrBufferStopSending(kTestStopSendingCode, kTestStreamId);
67 number_of_frames_ = 5u;
68 ping_frame_id_ = 6u;
69 EXPECT_EQ(number_of_frames_,
70 QuicControlFrameManagerPeer::QueueSize(manager_.get()));
71 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
72 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
73 EXPECT_TRUE(
74 manager_->IsControlFrameOutstanding(QuicFrame(&window_update_)));
75 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&blocked_)));
76 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&stop_sending_)));
77 EXPECT_FALSE(manager_->IsControlFrameOutstanding(
78 QuicFrame(QuicPingFrame(ping_frame_id_))));
79
80 EXPECT_FALSE(manager_->HasPendingRetransmission());
81 EXPECT_TRUE(manager_->WillingToWrite());
82 }
83
84 QuicRstStreamFrame rst_stream_ = {1, kTestStreamId, QUIC_STREAM_CANCELLED, 0};
85 QuicGoAwayFrame goaway_ = {2, QUIC_PEER_GOING_AWAY, kTestStreamId,
86 "Going away."};
87 QuicWindowUpdateFrame window_update_ = {3, kTestStreamId, 100};
88 QuicBlockedFrame blocked_ = {4, kTestStreamId};
89 QuicStopSendingFrame stop_sending_ = {5, kTestStreamId, kTestStopSendingCode};
90 MockQuicConnectionHelper helper_;
91 MockAlarmFactory alarm_factory_;
92 MockQuicConnection* connection_;
93 std::unique_ptr<StrictMock<MockQuicSession>> session_;
94 std::unique_ptr<QuicControlFrameManager> manager_;
95 QuicFrame frame_;
96 size_t number_of_frames_;
97 int ping_frame_id_;
98};
99
100TEST_F(QuicControlFrameManagerTest, OnControlFrameAcked) {
101 Initialize();
102 InSequence s;
103 EXPECT_CALL(*connection_, SendControlFrame(_))
104 .Times(3)
bnc5b3c3be2019-06-25 10:37:09 -0700105 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500106 EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
107 // Send control frames 1, 2, 3.
108 manager_->OnCanWrite();
109 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
110 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
111 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&window_update_)));
112 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&blocked_)));
113 EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&stop_sending_)));
114
115 EXPECT_FALSE(manager_->IsControlFrameOutstanding(
116 QuicFrame(QuicPingFrame(ping_frame_id_))));
117 EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&window_update_)));
118 EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&window_update_)));
119 EXPECT_EQ(number_of_frames_,
120 QuicControlFrameManagerPeer::QueueSize(manager_.get()));
121
122 EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&goaway_)));
123 EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
124 EXPECT_EQ(number_of_frames_,
125 QuicControlFrameManagerPeer::QueueSize(manager_.get()));
126 EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&rst_stream_)));
127 EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
128 // Only after the first frame in the queue is acked do the frames get
129 // removed ... now see that the length has been reduced by 3.
130 EXPECT_EQ(number_of_frames_ - 3u,
131 QuicControlFrameManagerPeer::QueueSize(manager_.get()));
132 // Duplicate ack.
133 EXPECT_FALSE(manager_->OnControlFrameAcked(QuicFrame(&goaway_)));
134
135 EXPECT_FALSE(manager_->HasPendingRetransmission());
136 EXPECT_TRUE(manager_->WillingToWrite());
137
138 // Send control frames 4, 5.
139 EXPECT_CALL(*connection_, SendControlFrame(_))
bnc5b3c3be2019-06-25 10:37:09 -0700140 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500141 manager_->OnCanWrite();
142 manager_->WritePing();
143 EXPECT_FALSE(manager_->WillingToWrite());
144}
145
146TEST_F(QuicControlFrameManagerTest, OnControlFrameLost) {
147 Initialize();
148 InSequence s;
149 EXPECT_CALL(*connection_, SendControlFrame(_))
150 .Times(3)
bnc5b3c3be2019-06-25 10:37:09 -0700151 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500152 EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
153 // Send control frames 1, 2, 3.
154 manager_->OnCanWrite();
155
156 // Lost control frames 1, 2, 3.
157 manager_->OnControlFrameLost(QuicFrame(&rst_stream_));
158 manager_->OnControlFrameLost(QuicFrame(&goaway_));
159 manager_->OnControlFrameLost(QuicFrame(&window_update_));
160 EXPECT_TRUE(manager_->HasPendingRetransmission());
161
162 // Ack control frame 2.
163 manager_->OnControlFrameAcked(QuicFrame(&goaway_));
164
165 // Retransmit control frames 1, 3.
166 EXPECT_CALL(*connection_, SendControlFrame(_))
167 .Times(2)
bnc5b3c3be2019-06-25 10:37:09 -0700168 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500169 manager_->OnCanWrite();
170 EXPECT_FALSE(manager_->HasPendingRetransmission());
171 EXPECT_TRUE(manager_->WillingToWrite());
172
173 // Send control frames 4, 5, and 6.
174 EXPECT_CALL(*connection_, SendControlFrame(_))
175 .Times(number_of_frames_ - 2u)
bnc5b3c3be2019-06-25 10:37:09 -0700176 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500177 manager_->OnCanWrite();
178 manager_->WritePing();
179 EXPECT_FALSE(manager_->WillingToWrite());
180}
181
182TEST_F(QuicControlFrameManagerTest, RetransmitControlFrame) {
183 Initialize();
184 InSequence s;
185 // Send control frames 1, 2, 3, 4.
186 EXPECT_CALL(*connection_, SendControlFrame(_))
187 .Times(number_of_frames_)
bnc5b3c3be2019-06-25 10:37:09 -0700188 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500189 manager_->OnCanWrite();
190
191 // Ack control frame 2.
192 manager_->OnControlFrameAcked(QuicFrame(&goaway_));
193 // Do not retransmit an acked frame.
194 EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
195 EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&goaway_)));
196
197 // Retransmit control frame 3.
198 EXPECT_CALL(*connection_, SendControlFrame(_))
bnc5b3c3be2019-06-25 10:37:09 -0700199 .WillOnce(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500200 EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&window_update_)));
201
202 // Retransmit control frame 4, and connection is write blocked.
203 EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
204 EXPECT_FALSE(manager_->RetransmitControlFrame(QuicFrame(&window_update_)));
205}
206
207TEST_F(QuicControlFrameManagerTest, DonotSendPingWithBufferedFrames) {
208 Initialize();
209 InSequence s;
210 EXPECT_CALL(*connection_, SendControlFrame(_))
bnc5b3c3be2019-06-25 10:37:09 -0700211 .WillOnce(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500212 EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false));
213 // Send control frame 1.
214 manager_->OnCanWrite();
215 EXPECT_FALSE(manager_->HasPendingRetransmission());
216 EXPECT_TRUE(manager_->WillingToWrite());
217
218 // Send PING when there is buffered frames.
219 manager_->WritePing();
220 // Verify only the buffered frames are sent.
221 EXPECT_CALL(*connection_, SendControlFrame(_))
222 .Times(number_of_frames_ - 1)
bnc5b3c3be2019-06-25 10:37:09 -0700223 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500224 manager_->OnCanWrite();
225 EXPECT_FALSE(manager_->HasPendingRetransmission());
226 EXPECT_FALSE(manager_->WillingToWrite());
227}
228
229TEST_F(QuicControlFrameManagerTest, DonotRetransmitOldWindowUpdates) {
230 Initialize();
231 // Send two more window updates of the same stream.
232 manager_->WriteOrBufferWindowUpdate(kTestStreamId, 200);
233 QuicWindowUpdateFrame window_update2(number_of_frames_ + 1, kTestStreamId,
234 200);
235
236 manager_->WriteOrBufferWindowUpdate(kTestStreamId, 300);
237 QuicWindowUpdateFrame window_update3(number_of_frames_ + 2, kTestStreamId,
238 300);
239 InSequence s;
240 // Flush all buffered control frames.
241 EXPECT_CALL(*connection_, SendControlFrame(_))
bnc5b3c3be2019-06-25 10:37:09 -0700242 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500243 manager_->OnCanWrite();
244
245 // Mark all 3 window updates as lost.
246 manager_->OnControlFrameLost(QuicFrame(&window_update_));
247 manager_->OnControlFrameLost(QuicFrame(&window_update2));
248 manager_->OnControlFrameLost(QuicFrame(&window_update3));
249 EXPECT_TRUE(manager_->HasPendingRetransmission());
250 EXPECT_TRUE(manager_->WillingToWrite());
251
252 // Verify only the latest window update gets retransmitted.
253 EXPECT_CALL(*connection_, SendControlFrame(_))
254 .WillOnce(Invoke(this, &QuicControlFrameManagerTest::SaveControlFrame));
255 manager_->OnCanWrite();
256 EXPECT_EQ(number_of_frames_ + 2u,
257 frame_.window_update_frame->control_frame_id);
258 EXPECT_FALSE(manager_->HasPendingRetransmission());
259 EXPECT_FALSE(manager_->WillingToWrite());
260 DeleteFrame(&frame_);
261}
262
263TEST_F(QuicControlFrameManagerTest, RetransmitWindowUpdateOfDifferentStreams) {
264 Initialize();
265 // Send two more window updates of different streams.
266 manager_->WriteOrBufferWindowUpdate(kTestStreamId + 2, 200);
267 QuicWindowUpdateFrame window_update2(5, kTestStreamId + 2, 200);
268
269 manager_->WriteOrBufferWindowUpdate(kTestStreamId + 4, 300);
270 QuicWindowUpdateFrame window_update3(6, kTestStreamId + 4, 300);
271 InSequence s;
272 // Flush all buffered control frames.
273 EXPECT_CALL(*connection_, SendControlFrame(_))
bnc5b3c3be2019-06-25 10:37:09 -0700274 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500275 manager_->OnCanWrite();
276
277 // Mark all 3 window updates as lost.
278 manager_->OnControlFrameLost(QuicFrame(&window_update_));
279 manager_->OnControlFrameLost(QuicFrame(&window_update2));
280 manager_->OnControlFrameLost(QuicFrame(&window_update3));
281 EXPECT_TRUE(manager_->HasPendingRetransmission());
282 EXPECT_TRUE(manager_->WillingToWrite());
283
284 // Verify all 3 window updates get retransmitted.
285 EXPECT_CALL(*connection_, SendControlFrame(_))
286 .Times(3)
bnc5b3c3be2019-06-25 10:37:09 -0700287 .WillRepeatedly(Invoke(&ClearControlFrame));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500288 manager_->OnCanWrite();
289 EXPECT_FALSE(manager_->HasPendingRetransmission());
290 EXPECT_FALSE(manager_->WillingToWrite());
291}
292
fayang83d7e3e2019-07-31 14:45:19 -0700293TEST_F(QuicControlFrameManagerTest, TooManyBufferedControlFrames) {
fayang83d7e3e2019-07-31 14:45:19 -0700294 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