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