blob: 4dc48a7c1d516035a0c492440a0999f621f21469 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2018 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/test_tools/simple_session_notifier.h"
6
bnc463f2352019-10-10 04:49:34 -07007#include <utility>
8
nharper46833c32019-05-15 21:33:05 -07009#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include "net/third_party/quiche/src/quic/core/quic_utils.h"
11#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
12#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
13#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
nharper46833c32019-05-15 21:33:05 -070014#include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015
16using testing::_;
17using testing::InSequence;
18using testing::Return;
19using testing::StrictMock;
20
21namespace quic {
22namespace test {
23namespace {
24
25class MockQuicConnectionWithSendStreamData : public MockQuicConnection {
26 public:
27 MockQuicConnectionWithSendStreamData(MockQuicConnectionHelper* helper,
28 MockAlarmFactory* alarm_factory,
29 Perspective perspective)
30 : MockQuicConnection(helper, alarm_factory, perspective) {}
31
32 MOCK_METHOD4(SendStreamData,
33 QuicConsumedData(QuicStreamId id,
34 size_t write_length,
35 QuicStreamOffset offset,
36 StreamSendingState state));
37};
38
39class SimpleSessionNotifierTest : public QuicTest {
40 public:
41 SimpleSessionNotifierTest()
42 : connection_(&helper_, &alarm_factory_, Perspective::IS_CLIENT),
43 notifier_(&connection_) {
44 connection_.set_visitor(&visitor_);
fayang58f71072019-11-05 08:47:02 -080045 connection_.SetSessionNotifier(&notifier_);
QUICHE teama6ef0a62019-03-07 20:34:33 -050046 EXPECT_FALSE(notifier_.WillingToWrite());
47 EXPECT_EQ(0u, notifier_.StreamBytesSent());
48 EXPECT_FALSE(notifier_.HasBufferedStreamData());
49 }
50
51 bool ControlFrameConsumed(const QuicFrame& frame) {
52 DeleteFrame(&const_cast<QuicFrame&>(frame));
53 return true;
54 }
55
56 MockQuicConnectionHelper helper_;
57 MockAlarmFactory alarm_factory_;
58 MockQuicConnectionVisitor visitor_;
59 StrictMock<MockQuicConnectionWithSendStreamData> connection_;
60 SimpleSessionNotifier notifier_;
61};
62
63TEST_F(SimpleSessionNotifierTest, WriteOrBufferData) {
64 InSequence s;
65 EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, NO_FIN))
66 .WillOnce(Return(QuicConsumedData(1024, false)));
67 notifier_.WriteOrBufferData(3, 1024, NO_FIN);
68 EXPECT_EQ(0u, notifier_.StreamBytesToSend());
69 EXPECT_CALL(connection_, SendStreamData(5, 512, 0, NO_FIN))
70 .WillOnce(Return(QuicConsumedData(512, false)));
71 notifier_.WriteOrBufferData(5, 512, NO_FIN);
72 EXPECT_FALSE(notifier_.WillingToWrite());
73 // Connection is blocked.
74 EXPECT_CALL(connection_, SendStreamData(5, 512, 512, FIN))
75 .WillOnce(Return(QuicConsumedData(256, false)));
76 notifier_.WriteOrBufferData(5, 512, FIN);
77 EXPECT_TRUE(notifier_.WillingToWrite());
78 EXPECT_EQ(1792u, notifier_.StreamBytesSent());
79 EXPECT_EQ(256u, notifier_.StreamBytesToSend());
80 EXPECT_TRUE(notifier_.HasBufferedStreamData());
81
82 // New data cannot be sent as connection is blocked.
83 EXPECT_CALL(connection_, SendStreamData(7, 1024, 0, FIN)).Times(0);
84 notifier_.WriteOrBufferData(7, 1024, FIN);
85 EXPECT_EQ(1792u, notifier_.StreamBytesSent());
86}
87
88TEST_F(SimpleSessionNotifierTest, WriteOrBufferRstStream) {
89 InSequence s;
90 EXPECT_CALL(connection_, SendStreamData(5, 1024, 0, FIN))
91 .WillOnce(Return(QuicConsumedData(1024, true)));
92 notifier_.WriteOrBufferData(5, 1024, FIN);
zhongyi1b2f7832019-06-14 13:31:34 -070093 EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(5));
94 EXPECT_TRUE(notifier_.HasUnackedStreamData());
QUICHE teama6ef0a62019-03-07 20:34:33 -050095
96 // Reset stream 5 with no error.
97 EXPECT_CALL(connection_, SendControlFrame(_))
98 .WillRepeatedly(
99 Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
100 notifier_.WriteOrBufferRstStream(5, QUIC_STREAM_NO_ERROR, 1024);
101 // Verify stream 5 is waiting for acks.
102 EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(5));
zhongyi1b2f7832019-06-14 13:31:34 -0700103 EXPECT_TRUE(notifier_.HasUnackedStreamData());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500104
105 // Reset stream 5 with error.
106 notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
107 EXPECT_FALSE(notifier_.StreamIsWaitingForAcks(5));
zhongyi1b2f7832019-06-14 13:31:34 -0700108 EXPECT_FALSE(notifier_.HasUnackedStreamData());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500109}
110
zhongyifbb25772019-04-10 16:54:08 -0700111TEST_F(SimpleSessionNotifierTest, WriteOrBufferPing) {
112 InSequence s;
113 // Write ping when connection is not write blocked.
114 EXPECT_CALL(connection_, SendControlFrame(_))
115 .WillRepeatedly(
116 Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
117 notifier_.WriteOrBufferPing();
118 EXPECT_EQ(0u, notifier_.StreamBytesToSend());
119 EXPECT_FALSE(notifier_.WillingToWrite());
120
121 // Write stream data and cause the connection to be write blocked.
122 EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, NO_FIN))
123 .WillOnce(Return(QuicConsumedData(1024, false)));
124 notifier_.WriteOrBufferData(3, 1024, NO_FIN);
125 EXPECT_EQ(0u, notifier_.StreamBytesToSend());
126 EXPECT_CALL(connection_, SendStreamData(5, 512, 0, NO_FIN))
127 .WillOnce(Return(QuicConsumedData(256, false)));
128 notifier_.WriteOrBufferData(5, 512, NO_FIN);
129 EXPECT_TRUE(notifier_.WillingToWrite());
130
131 // Connection is blocked.
132 EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
133 notifier_.WriteOrBufferPing();
134}
135
QUICHE teama6ef0a62019-03-07 20:34:33 -0500136TEST_F(SimpleSessionNotifierTest, NeuterUnencryptedData) {
nharper46833c32019-05-15 21:33:05 -0700137 if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
renjietangd983e062019-11-18 10:05:34 -0800138 // This test writes crypto data through crypto streams. It won't work when
139 // crypto frames are used instead.
nharper46833c32019-05-15 21:33:05 -0700140 return;
141 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500142 InSequence s;
QUICHE team6987b4a2019-03-15 16:23:04 -0700143 // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
144 connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500145 EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
146 connection_.transport_version()),
147 1024, 0, NO_FIN))
148 .WillOnce(Return(QuicConsumedData(1024, false)));
149 notifier_.WriteOrBufferData(
150 QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
151 NO_FIN);
152 // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
153 connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
154 EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
155 connection_.transport_version()),
156 1024, 1024, NO_FIN))
157 .WillOnce(Return(QuicConsumedData(1024, false)));
158 notifier_.WriteOrBufferData(
159 QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
160 NO_FIN);
161 // Ack [1024, 2048).
162 QuicStreamFrame stream_frame(
163 QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
164 1024, 1024);
QUICHE team9467db02019-05-30 09:38:45 -0700165 notifier_.OnFrameAcked(QuicFrame(stream_frame), QuicTime::Delta::Zero(),
166 QuicTime::Zero());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500167 EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(
168 QuicUtils::GetCryptoStreamId(connection_.transport_version())));
zhongyi1b2f7832019-06-14 13:31:34 -0700169 EXPECT_TRUE(notifier_.HasUnackedStreamData());
170
QUICHE teama6ef0a62019-03-07 20:34:33 -0500171 // Neuters unencrypted data.
172 notifier_.NeuterUnencryptedData();
173 EXPECT_FALSE(notifier_.StreamIsWaitingForAcks(
174 QuicUtils::GetCryptoStreamId(connection_.transport_version())));
zhongyi1b2f7832019-06-14 13:31:34 -0700175 EXPECT_FALSE(notifier_.HasUnackedStreamData());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500176}
177
178TEST_F(SimpleSessionNotifierTest, OnCanWrite) {
nharper46833c32019-05-15 21:33:05 -0700179 if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
renjietangd983e062019-11-18 10:05:34 -0800180 // This test writes crypto data through crypto streams. It won't work when
181 // crypto frames are used instead.
nharper46833c32019-05-15 21:33:05 -0700182 return;
183 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500184 InSequence s;
QUICHE team6987b4a2019-03-15 16:23:04 -0700185 // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
186 connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500187 EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
188 connection_.transport_version()),
189 1024, 0, NO_FIN))
190 .WillOnce(Return(QuicConsumedData(1024, false)));
191 notifier_.WriteOrBufferData(
192 QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
193 NO_FIN);
zhongyi1b2f7832019-06-14 13:31:34 -0700194
QUICHE teama6ef0a62019-03-07 20:34:33 -0500195 // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
196 connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
197 EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
198 connection_.transport_version()),
199 1024, 1024, NO_FIN))
200 .WillOnce(Return(QuicConsumedData(1024, false)));
201 notifier_.WriteOrBufferData(
202 QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
203 NO_FIN);
204 // Send stream 3 [0, 1024) and connection is blocked.
205 EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, FIN))
206 .WillOnce(Return(QuicConsumedData(512, false)));
207 notifier_.WriteOrBufferData(3, 1024, FIN);
208 // Send stream 5 [0, 1024).
209 EXPECT_CALL(connection_, SendStreamData(5, _, _, _)).Times(0);
210 notifier_.WriteOrBufferData(5, 1024, NO_FIN);
211 // Reset stream 5 with error.
212 EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
213 notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
214
215 // Lost crypto data [500, 1500) and stream 3 [0, 512).
216 QuicStreamFrame frame1(
217 QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 500,
218 1000);
219 QuicStreamFrame frame2(3, false, 0, 512);
220 notifier_.OnFrameLost(QuicFrame(frame1));
221 notifier_.OnFrameLost(QuicFrame(frame2));
222
223 // Connection becomes writable.
224 // Lost crypto data gets retransmitted as [500, 1024) and [1024, 1500), as
225 // they are in different encryption levels.
226 EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
227 connection_.transport_version()),
228 524, 500, NO_FIN))
229 .WillOnce(Return(QuicConsumedData(524, false)));
230 EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
231 connection_.transport_version()),
232 476, 1024, NO_FIN))
233 .WillOnce(Return(QuicConsumedData(476, false)));
234 // Lost stream 3 data gets retransmitted.
235 EXPECT_CALL(connection_, SendStreamData(3, 512, 0, NO_FIN))
236 .WillOnce(Return(QuicConsumedData(512, false)));
237 // Buffered control frames get sent.
238 EXPECT_CALL(connection_, SendControlFrame(_))
239 .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
240 // Buffered stream 3 data [512, 1024) gets sent.
241 EXPECT_CALL(connection_, SendStreamData(3, 512, 512, FIN))
242 .WillOnce(Return(QuicConsumedData(512, true)));
243 notifier_.OnCanWrite();
244 EXPECT_FALSE(notifier_.WillingToWrite());
245}
246
nharper46833c32019-05-15 21:33:05 -0700247TEST_F(SimpleSessionNotifierTest, OnCanWriteCryptoFrames) {
248 if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
249 return;
250 }
251 SimpleDataProducer producer;
252 connection_.SetDataProducer(&producer);
253 InSequence s;
254 // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
255 connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
256 EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 1024, 0))
257 .WillOnce(Invoke(&connection_,
258 &MockQuicConnection::QuicConnection_SendCryptoData));
fkastenholz85f18902019-05-28 12:47:00 -0700259 EXPECT_CALL(connection_, CloseConnection(QUIC_PACKET_WRITE_ERROR, _, _));
nharperfc707362019-08-08 17:44:24 -0700260 std::string crypto_data1(1024, 'a');
261 producer.SaveCryptoData(ENCRYPTION_INITIAL, 0, crypto_data1);
262 std::string crypto_data2(524, 'a');
263 producer.SaveCryptoData(ENCRYPTION_INITIAL, 500, crypto_data2);
nharper46833c32019-05-15 21:33:05 -0700264 notifier_.WriteCryptoData(ENCRYPTION_INITIAL, 1024, 0);
265 // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
266 connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
vasilvv0fc587f2019-09-06 13:33:08 -0700267 connection_.SetEncrypter(ENCRYPTION_ZERO_RTT, std::make_unique<NullEncrypter>(
nharper46833c32019-05-15 21:33:05 -0700268 Perspective::IS_CLIENT));
269 EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0))
270 .WillOnce(Invoke(&connection_,
271 &MockQuicConnection::QuicConnection_SendCryptoData));
nharperfc707362019-08-08 17:44:24 -0700272 std::string crypto_data3(1024, 'a');
273 producer.SaveCryptoData(ENCRYPTION_ZERO_RTT, 0, crypto_data3);
nharper46833c32019-05-15 21:33:05 -0700274 notifier_.WriteCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0);
275 // Send stream 3 [0, 1024) and connection is blocked.
276 EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, FIN))
277 .WillOnce(Return(QuicConsumedData(512, false)));
278 notifier_.WriteOrBufferData(3, 1024, FIN);
279 // Send stream 5 [0, 1024).
280 EXPECT_CALL(connection_, SendStreamData(5, _, _, _)).Times(0);
281 notifier_.WriteOrBufferData(5, 1024, NO_FIN);
282 // Reset stream 5 with error.
283 EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
284 notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
285
286 // Lost crypto data [500, 1500) and stream 3 [0, 512).
287 QuicCryptoFrame crypto_frame1(ENCRYPTION_INITIAL, 500, 524);
288 QuicCryptoFrame crypto_frame2(ENCRYPTION_ZERO_RTT, 0, 476);
289 QuicStreamFrame stream3_frame(3, false, 0, 512);
290 notifier_.OnFrameLost(QuicFrame(&crypto_frame1));
291 notifier_.OnFrameLost(QuicFrame(&crypto_frame2));
292 notifier_.OnFrameLost(QuicFrame(stream3_frame));
293
294 // Connection becomes writable.
295 // Lost crypto data gets retransmitted as [500, 1024) and [1024, 1500), as
296 // they are in different encryption levels.
297 EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 524, 500))
298 .WillOnce(Invoke(&connection_,
299 &MockQuicConnection::QuicConnection_SendCryptoData));
300 EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 476, 0))
301 .WillOnce(Invoke(&connection_,
302 &MockQuicConnection::QuicConnection_SendCryptoData));
303 // Lost stream 3 data gets retransmitted.
304 EXPECT_CALL(connection_, SendStreamData(3, 512, 0, NO_FIN))
305 .WillOnce(Return(QuicConsumedData(512, false)));
306 // Buffered control frames get sent.
307 EXPECT_CALL(connection_, SendControlFrame(_))
308 .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
309 // Buffered stream 3 data [512, 1024) gets sent.
310 EXPECT_CALL(connection_, SendStreamData(3, 512, 512, FIN))
311 .WillOnce(Return(QuicConsumedData(512, true)));
312 notifier_.OnCanWrite();
313 EXPECT_FALSE(notifier_.WillingToWrite());
314}
315
QUICHE teama6ef0a62019-03-07 20:34:33 -0500316TEST_F(SimpleSessionNotifierTest, RetransmitFrames) {
317 InSequence s;
318 // Send stream 3 data [0, 10) and fin.
319 EXPECT_CALL(connection_, SendStreamData(3, 10, 0, FIN))
320 .WillOnce(Return(QuicConsumedData(10, true)));
321 notifier_.WriteOrBufferData(3, 10, FIN);
322 QuicStreamFrame frame1(3, true, 0, 10);
323 // Send stream 5 [0, 10) and fin.
324 EXPECT_CALL(connection_, SendStreamData(5, 10, 0, FIN))
325 .WillOnce(Return(QuicConsumedData(10, true)));
326 notifier_.WriteOrBufferData(5, 10, FIN);
327 QuicStreamFrame frame2(5, true, 0, 10);
328 // Reset stream 5 with no error.
329 EXPECT_CALL(connection_, SendControlFrame(_))
330 .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
331 notifier_.WriteOrBufferRstStream(5, QUIC_STREAM_NO_ERROR, 10);
332
333 // Ack stream 3 [3, 7), and stream 5 [8, 10).
334 QuicStreamFrame ack_frame1(3, false, 3, 4);
335 QuicStreamFrame ack_frame2(5, false, 8, 2);
QUICHE team9467db02019-05-30 09:38:45 -0700336 notifier_.OnFrameAcked(QuicFrame(ack_frame1), QuicTime::Delta::Zero(),
337 QuicTime::Zero());
338 notifier_.OnFrameAcked(QuicFrame(ack_frame2), QuicTime::Delta::Zero(),
339 QuicTime::Zero());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500340 EXPECT_FALSE(notifier_.WillingToWrite());
341
342 // Force to send.
343 QuicRstStreamFrame rst_stream(1, 5, QUIC_STREAM_NO_ERROR, 10);
344 QuicFrames frames;
345 frames.push_back(QuicFrame(frame2));
346 frames.push_back(QuicFrame(&rst_stream));
347 frames.push_back(QuicFrame(frame1));
348 // stream 5 data [0, 8), fin only are retransmitted.
349 EXPECT_CALL(connection_, SendStreamData(5, 8, 0, NO_FIN))
350 .WillOnce(Return(QuicConsumedData(8, false)));
351 EXPECT_CALL(connection_, SendStreamData(5, 0, 10, FIN))
352 .WillOnce(Return(QuicConsumedData(0, true)));
353 // rst_stream is retransmitted.
354 EXPECT_CALL(connection_, SendControlFrame(_))
355 .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
356 // stream 3 data [0, 3) is retransmitted and connection is blocked.
357 EXPECT_CALL(connection_, SendStreamData(3, 3, 0, NO_FIN))
358 .WillOnce(Return(QuicConsumedData(2, false)));
359 notifier_.RetransmitFrames(frames, RTO_RETRANSMISSION);
360 EXPECT_FALSE(notifier_.WillingToWrite());
361}
362
363} // namespace
364} // namespace test
365} // namespace quic