1 // Copyright (c) 2012 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.
5 #include "net/quic/reliable_quic_stream.h"
7 #include "net/quic/quic_ack_notifier.h"
8 #include "net/quic/quic_connection.h"
9 #include "net/quic/quic_utils.h"
10 #include "net/quic/quic_write_blocked_list.h"
11 #include "net/quic/spdy_utils.h"
12 #include "net/quic/test_tools/quic_session_peer.h"
13 #include "net/quic/test_tools/quic_test_utils.h"
14 #include "net/quic/test_tools/reliable_quic_stream_peer.h"
15 #include "net/test/gtest_util.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gmock_mutant.h"
19 using base::StringPiece
;
22 using testing::CreateFunctor
;
23 using testing::InSequence
;
24 using testing::Invoke
;
25 using testing::Return
;
26 using testing::SaveArg
;
27 using testing::StrictMock
;
28 using testing::WithArgs
;
34 const char kData1
[] = "FooAndBar";
35 const char kData2
[] = "EepAndBaz";
36 const size_t kDataLen
= 9;
37 const QuicConnectionId kStreamId
= 3;
38 const bool kIsServer
= true;
39 const bool kShouldProcessData
= true;
41 class TestStream
: public ReliableQuicStream
{
43 TestStream(QuicStreamId id
,
45 bool should_process_data
)
46 : ReliableQuicStream(id
, session
),
47 should_process_data_(should_process_data
) {}
49 virtual uint32
ProcessRawData(const char* data
, uint32 data_len
) OVERRIDE
{
50 EXPECT_NE(0u, data_len
);
51 DVLOG(1) << "ProcessData data_len: " << data_len
;
52 data_
+= string(data
, data_len
);
53 return should_process_data_
? data_len
: 0;
56 virtual QuicPriority
EffectivePriority() const OVERRIDE
{
57 return QuicUtils::HighestPriority();
60 using ReliableQuicStream::WriteOrBufferData
;
61 using ReliableQuicStream::CloseReadSide
;
62 using ReliableQuicStream::CloseWriteSide
;
63 using ReliableQuicStream::OnClose
;
66 bool should_process_data_
;
70 class ReliableQuicStreamTest
: public ::testing::TestWithParam
<bool> {
72 ReliableQuicStreamTest() {
73 headers_
[":host"] = "www.google.com";
74 headers_
[":path"] = "/index.hml";
75 headers_
[":scheme"] = "https";
77 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
79 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
80 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
81 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
82 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
83 "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
84 "1zFMi5vzcns38-8_Sns; "
85 "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
86 "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
87 "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
88 "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
89 "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
90 "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
91 "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
92 "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
93 "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
94 "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
95 "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
96 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
97 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
98 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
99 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
102 void Initialize(bool stream_should_process_data
) {
103 connection_
= new StrictMock
<MockConnection
>(kIsServer
);
104 session_
.reset(new StrictMock
<MockSession
>(connection_
));
105 stream_
.reset(new TestStream(kStreamId
, session_
.get(),
106 stream_should_process_data
));
107 stream2_
.reset(new TestStream(kStreamId
+ 2, session_
.get(),
108 stream_should_process_data
));
109 write_blocked_list_
=
110 QuicSessionPeer::GetWriteblockedStreams(session_
.get());
113 bool fin_sent() { return ReliableQuicStreamPeer::FinSent(stream_
.get()); }
114 bool rst_sent() { return ReliableQuicStreamPeer::RstSent(stream_
.get()); }
117 MockConnection
* connection_
;
118 scoped_ptr
<MockSession
> session_
;
119 scoped_ptr
<TestStream
> stream_
;
120 scoped_ptr
<TestStream
> stream2_
;
121 SpdyHeaderBlock headers_
;
122 QuicWriteBlockedList
* write_blocked_list_
;
125 TEST_F(ReliableQuicStreamTest
, WriteAllData
) {
126 Initialize(kShouldProcessData
);
128 connection_
->options()->max_packet_length
=
129 1 + QuicPacketCreator::StreamFramePacketOverhead(
130 connection_
->version(), PACKET_8BYTE_CONNECTION_ID
, !kIncludeVersion
,
131 PACKET_6BYTE_SEQUENCE_NUMBER
, NOT_IN_FEC_GROUP
);
132 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(
133 Return(QuicConsumedData(kDataLen
, true)));
134 stream_
->WriteOrBufferData(kData1
, false, NULL
);
135 EXPECT_FALSE(write_blocked_list_
->HasWriteBlockedStreams());
138 TEST_F(ReliableQuicStreamTest
, NoBlockingIfNoDataOrFin
) {
139 Initialize(kShouldProcessData
);
141 // Write no data and no fin. If we consume nothing we should not be write
143 EXPECT_DFATAL(stream_
->WriteOrBufferData(StringPiece(), false, NULL
), "");
144 EXPECT_FALSE(write_blocked_list_
->HasWriteBlockedStreams());
147 TEST_F(ReliableQuicStreamTest
, BlockIfOnlySomeDataConsumed
) {
148 Initialize(kShouldProcessData
);
150 // Write some data and no fin. If we consume some but not all of the data,
151 // we should be write blocked a not all the data was consumed.
152 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(
153 Return(QuicConsumedData(1, false)));
154 stream_
->WriteOrBufferData(StringPiece(kData1
, 2), false, NULL
);
155 ASSERT_EQ(1u, write_blocked_list_
->NumBlockedStreams());
159 TEST_F(ReliableQuicStreamTest
, BlockIfFinNotConsumedWithData
) {
160 Initialize(kShouldProcessData
);
162 // Write some data and no fin. If we consume all the data but not the fin,
163 // we should be write blocked because the fin was not consumed.
164 // (This should never actually happen as the fin should be sent out with the
166 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(
167 Return(QuicConsumedData(2, false)));
168 stream_
->WriteOrBufferData(StringPiece(kData1
, 2), true, NULL
);
169 ASSERT_EQ(1u, write_blocked_list_
->NumBlockedStreams());
172 TEST_F(ReliableQuicStreamTest
, BlockIfSoloFinNotConsumed
) {
173 Initialize(kShouldProcessData
);
175 // Write no data and a fin. If we consume nothing we should be write blocked,
176 // as the fin was not consumed.
177 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(
178 Return(QuicConsumedData(0, false)));
179 stream_
->WriteOrBufferData(StringPiece(), true, NULL
);
180 ASSERT_EQ(1u, write_blocked_list_
->NumBlockedStreams());
183 TEST_F(ReliableQuicStreamTest
, WriteOrBufferData
) {
184 Initialize(kShouldProcessData
);
186 EXPECT_FALSE(write_blocked_list_
->HasWriteBlockedStreams());
187 connection_
->options()->max_packet_length
=
188 1 + QuicPacketCreator::StreamFramePacketOverhead(
189 connection_
->version(), PACKET_8BYTE_CONNECTION_ID
, !kIncludeVersion
,
190 PACKET_6BYTE_SEQUENCE_NUMBER
, NOT_IN_FEC_GROUP
);
191 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, _
)).WillOnce(
192 Return(QuicConsumedData(kDataLen
- 1, false)));
193 stream_
->WriteOrBufferData(kData1
, false, NULL
);
194 EXPECT_TRUE(write_blocked_list_
->HasWriteBlockedStreams());
196 // Queue a bytes_consumed write.
197 stream_
->WriteOrBufferData(kData2
, false, NULL
);
199 // Make sure we get the tail of the first write followed by the bytes_consumed
201 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, _
)).
202 WillOnce(Return(QuicConsumedData(1, false)));
203 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, _
)).
204 WillOnce(Return(QuicConsumedData(kDataLen
- 2, false)));
205 stream_
->OnCanWrite();
207 // And finally the end of the bytes_consumed.
208 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, _
)).
209 WillOnce(Return(QuicConsumedData(2, true)));
210 stream_
->OnCanWrite();
213 TEST_F(ReliableQuicStreamTest
, ConnectionCloseAfterStreamClose
) {
214 Initialize(kShouldProcessData
);
216 stream_
->CloseReadSide();
217 stream_
->CloseWriteSide();
218 EXPECT_EQ(QUIC_STREAM_NO_ERROR
, stream_
->stream_error());
219 EXPECT_EQ(QUIC_NO_ERROR
, stream_
->connection_error());
220 stream_
->OnConnectionClosed(QUIC_INTERNAL_ERROR
, false);
221 EXPECT_EQ(QUIC_STREAM_NO_ERROR
, stream_
->stream_error());
222 EXPECT_EQ(QUIC_NO_ERROR
, stream_
->connection_error());
225 TEST_F(ReliableQuicStreamTest
, RstAlwaysSentIfNoFinSent
) {
226 // For flow control accounting, a stream must send either a FIN or a RST frame
227 // before termination.
228 // Test that if no FIN has been sent, we send a RST.
230 Initialize(kShouldProcessData
);
231 EXPECT_FALSE(fin_sent());
232 EXPECT_FALSE(rst_sent());
234 // Write some data, with no FIN.
235 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(
236 Return(QuicConsumedData(1, false)));
237 stream_
->WriteOrBufferData(StringPiece(kData1
, 1), false, NULL
);
238 EXPECT_FALSE(fin_sent());
239 EXPECT_FALSE(rst_sent());
241 // Now close the stream, and expect that we send a RST.
242 EXPECT_CALL(*session_
, SendRstStream(_
, _
, _
));
244 EXPECT_FALSE(fin_sent());
245 EXPECT_TRUE(rst_sent());
248 TEST_F(ReliableQuicStreamTest
, RstNotSentIfFinSent
) {
249 // For flow control accounting, a stream must send either a FIN or a RST frame
250 // before termination.
251 // Test that if a FIN has been sent, we don't also send a RST.
253 Initialize(kShouldProcessData
);
254 EXPECT_FALSE(fin_sent());
255 EXPECT_FALSE(rst_sent());
257 // Write some data, with FIN.
258 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(
259 Return(QuicConsumedData(1, true)));
260 stream_
->WriteOrBufferData(StringPiece(kData1
, 1), true, NULL
);
261 EXPECT_TRUE(fin_sent());
262 EXPECT_FALSE(rst_sent());
264 // Now close the stream, and expect that we do not send a RST.
266 EXPECT_TRUE(fin_sent());
267 EXPECT_FALSE(rst_sent());
270 TEST_F(ReliableQuicStreamTest
, OnlySendOneRst
) {
271 // For flow control accounting, a stream must send either a FIN or a RST frame
272 // before termination.
273 // Test that if a stream sends a RST, it doesn't send an additional RST during
274 // OnClose() (this shouldn't be harmful, but we shouldn't do it anyway...)
276 Initialize(kShouldProcessData
);
277 EXPECT_FALSE(fin_sent());
278 EXPECT_FALSE(rst_sent());
281 const int expected_resets
= 1;
282 EXPECT_CALL(*session_
, SendRstStream(_
, _
, _
)).Times(expected_resets
);
283 stream_
->Reset(QUIC_STREAM_CANCELLED
);
284 EXPECT_FALSE(fin_sent());
285 EXPECT_TRUE(rst_sent());
287 // Now close the stream (any further resets being sent would break the
288 // expectation above).
290 EXPECT_FALSE(fin_sent());
291 EXPECT_TRUE(rst_sent());
294 void SaveProxyAckNotifierDelegate(
295 scoped_refptr
<QuicAckNotifier::DelegateInterface
>* delegate_out
,
296 QuicAckNotifier::DelegateInterface
* delegate
) {
297 *delegate_out
= delegate
;
299 TEST_F(ReliableQuicStreamTest
, WriteOrBufferDataWithQuicAckNotifier
) {
300 Initialize(kShouldProcessData
);
302 scoped_refptr
<MockAckNotifierDelegate
> delegate(
303 new StrictMock
<MockAckNotifierDelegate
>);
305 const int kDataSize
= 16 * 1024;
306 const string
kData(kDataSize
, 'a');
308 const int kFirstWriteSize
= 100;
309 const int kSecondWriteSize
= 50;
310 const int kLastWriteSize
= kDataSize
- kFirstWriteSize
- kSecondWriteSize
;
312 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
314 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(DoAll(
315 WithArgs
<4>(Invoke(CreateFunctor(
316 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
317 Return(QuicConsumedData(kFirstWriteSize
, false))));
318 stream_
->WriteOrBufferData(kData
, false, delegate
.get());
319 EXPECT_TRUE(write_blocked_list_
->HasWriteBlockedStreams());
321 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, proxy_delegate
.get())).
323 Return(QuicConsumedData(kSecondWriteSize
, false)));
324 stream_
->OnCanWrite();
326 // No ack expected for an empty write.
327 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, proxy_delegate
.get())).
329 Return(QuicConsumedData(0, false)));
330 stream_
->OnCanWrite();
332 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, proxy_delegate
.get())).
334 Return(QuicConsumedData(kLastWriteSize
, false)));
335 stream_
->OnCanWrite();
337 // There were two writes, so OnAckNotification is not propagated
338 // until the third Ack arrives.
339 proxy_delegate
->OnAckNotification(1, 2, 3, 4);
340 proxy_delegate
->OnAckNotification(10, 20, 30, 40);
342 // The arguments to delegate->OnAckNotification are the sum of the
343 // arguments to proxy_delegate OnAckNotification calls.
344 EXPECT_CALL(*delegate
, OnAckNotification(111, 222, 333, 444));
345 proxy_delegate
->OnAckNotification(100, 200, 300, 400);
348 // Verify delegate behavior when packets are acked before the
349 // WritevData call that sends out the last byte.
350 TEST_F(ReliableQuicStreamTest
, WriteOrBufferDataAckNotificationBeforeFlush
) {
351 Initialize(kShouldProcessData
);
353 scoped_refptr
<MockAckNotifierDelegate
> delegate(
354 new StrictMock
<MockAckNotifierDelegate
>);
356 const int kDataSize
= 16 * 1024;
357 const string
kData(kDataSize
, 'a');
359 const int kInitialWriteSize
= 100;
361 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
363 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(DoAll(
364 WithArgs
<4>(Invoke(CreateFunctor(
365 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
366 Return(QuicConsumedData(kInitialWriteSize
, false))));
367 stream_
->WriteOrBufferData(kData
, false, delegate
.get());
368 EXPECT_TRUE(write_blocked_list_
->HasWriteBlockedStreams());
370 // Handle the ack of the first write.
371 proxy_delegate
->OnAckNotification(1, 2, 3, 4);
372 proxy_delegate
= NULL
;
374 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(DoAll(
375 WithArgs
<4>(Invoke(CreateFunctor(
376 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
377 Return(QuicConsumedData(kDataSize
- kInitialWriteSize
, false))));
378 stream_
->OnCanWrite();
380 // Handle the ack for the second write.
381 EXPECT_CALL(*delegate
, OnAckNotification(101, 202, 303, 404));
382 proxy_delegate
->OnAckNotification(100, 200, 300, 400);
385 // Verify delegate behavior when WriteOrBufferData does not buffer.
386 TEST_F(ReliableQuicStreamTest
, WriteAndBufferDataWithAckNotiferNoBuffer
) {
387 Initialize(kShouldProcessData
);
389 scoped_refptr
<MockAckNotifierDelegate
> delegate(
390 new StrictMock
<MockAckNotifierDelegate
>);
392 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
394 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(DoAll(
395 WithArgs
<4>(Invoke(CreateFunctor(
396 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
397 Return(QuicConsumedData(kDataLen
, true))));
398 stream_
->WriteOrBufferData(kData1
, true, delegate
.get());
399 EXPECT_FALSE(write_blocked_list_
->HasWriteBlockedStreams());
402 EXPECT_CALL(*delegate
, OnAckNotification(1, 2, 3, 4));
403 proxy_delegate
->OnAckNotification(1, 2, 3, 4);
406 // Verify delegate behavior when WriteOrBufferData buffers all the data.
407 TEST_F(ReliableQuicStreamTest
, BufferOnWriteAndBufferDataWithAckNotifer
) {
408 Initialize(kShouldProcessData
);
410 scoped_refptr
<MockAckNotifierDelegate
> delegate(
411 new StrictMock
<MockAckNotifierDelegate
>);
413 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
415 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(
416 Return(QuicConsumedData(0, false)));
417 stream_
->WriteOrBufferData(kData1
, true, delegate
.get());
418 EXPECT_TRUE(write_blocked_list_
->HasWriteBlockedStreams());
420 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(DoAll(
421 WithArgs
<4>(Invoke(CreateFunctor(
422 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
423 Return(QuicConsumedData(kDataLen
, true))));
424 stream_
->OnCanWrite();
427 EXPECT_CALL(*delegate
, OnAckNotification(1, 2, 3, 4));
428 proxy_delegate
->OnAckNotification(1, 2, 3, 4);
431 // Verify delegate behavior when WriteOrBufferData when the FIN is
432 // sent out in a different packet.
433 TEST_F(ReliableQuicStreamTest
, WriteAndBufferDataWithAckNotiferOnlyFinRemains
) {
434 Initialize(kShouldProcessData
);
436 scoped_refptr
<MockAckNotifierDelegate
> delegate(
437 new StrictMock
<MockAckNotifierDelegate
>);
439 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
441 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(DoAll(
442 WithArgs
<4>(Invoke(CreateFunctor(
443 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
444 Return(QuicConsumedData(kDataLen
, false))));
445 stream_
->WriteOrBufferData(kData1
, true, delegate
.get());
446 EXPECT_TRUE(write_blocked_list_
->HasWriteBlockedStreams());
448 EXPECT_CALL(*session_
, WritevData(kStreamId
, _
, _
, _
, _
)).WillOnce(DoAll(
449 WithArgs
<4>(Invoke(CreateFunctor(
450 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
451 Return(QuicConsumedData(0, true))));
452 stream_
->OnCanWrite();
455 proxy_delegate
->OnAckNotification(1, 2, 3, 4);
456 EXPECT_CALL(*delegate
, OnAckNotification(11, 22, 33, 44));
457 proxy_delegate
->OnAckNotification(10, 20, 30, 40);