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_config_peer.h"
13 #include "net/quic/test_tools/quic_connection_peer.h"
14 #include "net/quic/test_tools/quic_flow_controller_peer.h"
15 #include "net/quic/test_tools/quic_session_peer.h"
16 #include "net/quic/test_tools/quic_test_utils.h"
17 #include "net/quic/test_tools/reliable_quic_stream_peer.h"
18 #include "net/test/gtest_util.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gmock_mutant.h"
22 using base::StringPiece
;
24 using testing::CreateFunctor
;
25 using testing::InSequence
;
26 using testing::Invoke
;
27 using testing::Return
;
28 using testing::SaveArg
;
29 using testing::StrictMock
;
30 using testing::WithArgs
;
37 const char kData1
[] = "FooAndBar";
38 const char kData2
[] = "EepAndBaz";
39 const size_t kDataLen
= 9;
40 const bool kIsServer
= true;
41 const bool kShouldProcessData
= true;
43 class TestStream
: public ReliableQuicStream
{
45 TestStream(QuicStreamId id
,
47 bool should_process_data
)
48 : ReliableQuicStream(id
, session
),
49 should_process_data_(should_process_data
) {}
51 virtual uint32
ProcessRawData(const char* data
, uint32 data_len
) OVERRIDE
{
52 EXPECT_NE(0u, data_len
);
53 DVLOG(1) << "ProcessData data_len: " << data_len
;
54 data_
+= string(data
, data_len
);
55 return should_process_data_
? data_len
: 0;
58 virtual QuicPriority
EffectivePriority() const OVERRIDE
{
59 return QuicUtils::HighestPriority();
62 using ReliableQuicStream::WriteOrBufferData
;
63 using ReliableQuicStream::CloseReadSide
;
64 using ReliableQuicStream::CloseWriteSide
;
65 using ReliableQuicStream::OnClose
;
68 bool should_process_data_
;
72 class ReliableQuicStreamTest
: public ::testing::TestWithParam
<bool> {
74 ReliableQuicStreamTest()
75 : initial_flow_control_window_bytes_(kMaxPacketSize
),
76 zero_(QuicTime::Delta::Zero()),
77 supported_versions_(QuicSupportedVersions()) {
78 headers_
[":host"] = "www.google.com";
79 headers_
[":path"] = "/index.hml";
80 headers_
[":scheme"] = "https";
82 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
84 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
85 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
86 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
87 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
88 "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
89 "1zFMi5vzcns38-8_Sns; "
90 "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
91 "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
92 "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
93 "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
94 "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
95 "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
96 "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
97 "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
98 "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
99 "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
100 "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
101 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
102 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
103 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
104 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
107 void set_supported_versions(const QuicVersionVector
& versions
) {
108 supported_versions_
= versions
;
111 void Initialize(bool stream_should_process_data
) {
113 new StrictMock
<MockConnection
>(kIsServer
, supported_versions_
);
114 session_
.reset(new StrictMock
<MockSession
>(connection_
));
116 // New streams rely on having the peer's flow control receive window
117 // negotiated in the config.
118 QuicConfigPeer::SetReceivedInitialFlowControlWindow(
119 session_
->config(), initial_flow_control_window_bytes_
);
120 QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(
121 session_
->config(), initial_flow_control_window_bytes_
);
123 stream_
.reset(new TestStream(kHeadersStreamId
, session_
.get(),
124 stream_should_process_data
));
125 write_blocked_list_
=
126 QuicSessionPeer::GetWriteBlockedStreams(session_
.get());
129 bool fin_sent() { return ReliableQuicStreamPeer::FinSent(stream_
.get()); }
130 bool rst_sent() { return ReliableQuicStreamPeer::RstSent(stream_
.get()); }
132 void set_initial_flow_control_window_bytes(uint32 val
) {
133 initial_flow_control_window_bytes_
= val
;
136 bool HasWriteBlockedStreams() {
137 return write_blocked_list_
->HasWriteBlockedCryptoOrHeadersStream() ||
138 write_blocked_list_
->HasWriteBlockedDataStreams();
142 MockConnection
* connection_
;
143 scoped_ptr
<MockSession
> session_
;
144 scoped_ptr
<TestStream
> stream_
;
145 SpdyHeaderBlock headers_
;
146 QuicWriteBlockedList
* write_blocked_list_
;
147 uint32 initial_flow_control_window_bytes_
;
148 QuicTime::Delta zero_
;
149 QuicVersionVector supported_versions_
;
152 TEST_F(ReliableQuicStreamTest
, WriteAllData
) {
153 Initialize(kShouldProcessData
);
155 size_t length
= 1 + QuicPacketCreator::StreamFramePacketOverhead(
156 PACKET_8BYTE_CONNECTION_ID
, !kIncludeVersion
,
157 PACKET_6BYTE_SEQUENCE_NUMBER
, 0u, NOT_IN_FEC_GROUP
);
158 QuicConnectionPeer::GetPacketCreator(connection_
)->set_max_packet_length(
161 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
)).WillOnce(
162 Return(QuicConsumedData(kDataLen
, true)));
163 stream_
->WriteOrBufferData(kData1
, false, NULL
);
164 EXPECT_FALSE(HasWriteBlockedStreams());
167 TEST_F(ReliableQuicStreamTest
, NoBlockingIfNoDataOrFin
) {
168 Initialize(kShouldProcessData
);
170 // Write no data and no fin. If we consume nothing we should not be write
172 EXPECT_DFATAL(stream_
->WriteOrBufferData(StringPiece(), false, NULL
), "");
173 EXPECT_FALSE(HasWriteBlockedStreams());
176 TEST_F(ReliableQuicStreamTest
, BlockIfOnlySomeDataConsumed
) {
177 Initialize(kShouldProcessData
);
179 // Write some data and no fin. If we consume some but not all of the data,
180 // we should be write blocked a not all the data was consumed.
181 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
182 .WillOnce(Return(QuicConsumedData(1, false)));
183 stream_
->WriteOrBufferData(StringPiece(kData1
, 2), false, NULL
);
184 ASSERT_EQ(1u, write_blocked_list_
->NumBlockedStreams());
187 TEST_F(ReliableQuicStreamTest
, BlockIfFinNotConsumedWithData
) {
188 Initialize(kShouldProcessData
);
190 // Write some data and no fin. If we consume all the data but not the fin,
191 // we should be write blocked because the fin was not consumed.
192 // (This should never actually happen as the fin should be sent out with the
194 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
195 .WillOnce(Return(QuicConsumedData(2, false)));
196 stream_
->WriteOrBufferData(StringPiece(kData1
, 2), true, NULL
);
197 ASSERT_EQ(1u, write_blocked_list_
->NumBlockedStreams());
200 TEST_F(ReliableQuicStreamTest
, BlockIfSoloFinNotConsumed
) {
201 Initialize(kShouldProcessData
);
203 // Write no data and a fin. If we consume nothing we should be write blocked,
204 // as the fin was not consumed.
205 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
206 .WillOnce(Return(QuicConsumedData(0, false)));
207 stream_
->WriteOrBufferData(StringPiece(), true, NULL
);
208 ASSERT_EQ(1u, write_blocked_list_
->NumBlockedStreams());
211 TEST_F(ReliableQuicStreamTest
, WriteOrBufferData
) {
212 Initialize(kShouldProcessData
);
214 EXPECT_FALSE(HasWriteBlockedStreams());
215 size_t length
= 1 + QuicPacketCreator::StreamFramePacketOverhead(
216 PACKET_8BYTE_CONNECTION_ID
, !kIncludeVersion
,
217 PACKET_6BYTE_SEQUENCE_NUMBER
, 0u, NOT_IN_FEC_GROUP
);
218 QuicConnectionPeer::GetPacketCreator(connection_
)->set_max_packet_length(
221 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, _
, _
)).WillOnce(
222 Return(QuicConsumedData(kDataLen
- 1, false)));
223 stream_
->WriteOrBufferData(kData1
, false, NULL
);
224 EXPECT_TRUE(HasWriteBlockedStreams());
226 // Queue a bytes_consumed write.
227 stream_
->WriteOrBufferData(kData2
, false, NULL
);
229 // Make sure we get the tail of the first write followed by the bytes_consumed
231 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, _
, _
)).
232 WillOnce(Return(QuicConsumedData(1, false)));
233 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, _
, _
)).
234 WillOnce(Return(QuicConsumedData(kDataLen
- 2, false)));
235 stream_
->OnCanWrite();
237 // And finally the end of the bytes_consumed.
238 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, _
, _
)).
239 WillOnce(Return(QuicConsumedData(2, true)));
240 stream_
->OnCanWrite();
243 TEST_F(ReliableQuicStreamTest
, WriteOrBufferDataWithFecProtectAlways
) {
244 Initialize(kShouldProcessData
);
246 // Set FEC policy on stream.
247 ReliableQuicStreamPeer::SetFecPolicy(stream_
.get(), FEC_PROTECT_ALWAYS
);
249 EXPECT_FALSE(HasWriteBlockedStreams());
250 size_t length
= 1 + QuicPacketCreator::StreamFramePacketOverhead(
251 PACKET_8BYTE_CONNECTION_ID
, !kIncludeVersion
,
252 PACKET_6BYTE_SEQUENCE_NUMBER
, 0u, IN_FEC_GROUP
);
253 QuicConnectionPeer::GetPacketCreator(connection_
)->set_max_packet_length(
256 // Write first data onto stream, which will cause one session write.
257 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MUST_FEC_PROTECT
, _
)).WillOnce(
258 Return(QuicConsumedData(kDataLen
- 1, false)));
259 stream_
->WriteOrBufferData(kData1
, false, NULL
);
260 EXPECT_TRUE(HasWriteBlockedStreams());
262 // Queue a bytes_consumed write.
263 stream_
->WriteOrBufferData(kData2
, false, NULL
);
265 // Make sure we get the tail of the first write followed by the bytes_consumed
267 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MUST_FEC_PROTECT
, _
)).
268 WillOnce(Return(QuicConsumedData(1, false)));
269 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MUST_FEC_PROTECT
, _
)).
270 WillOnce(Return(QuicConsumedData(kDataLen
- 2, false)));
271 stream_
->OnCanWrite();
273 // And finally the end of the bytes_consumed.
274 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MUST_FEC_PROTECT
, _
)).
275 WillOnce(Return(QuicConsumedData(2, true)));
276 stream_
->OnCanWrite();
279 TEST_F(ReliableQuicStreamTest
, WriteOrBufferDataWithFecProtectOptional
) {
280 Initialize(kShouldProcessData
);
282 // Set FEC policy on stream.
283 ReliableQuicStreamPeer::SetFecPolicy(stream_
.get(), FEC_PROTECT_OPTIONAL
);
285 EXPECT_FALSE(HasWriteBlockedStreams());
286 size_t length
= 1 + QuicPacketCreator::StreamFramePacketOverhead(
287 PACKET_8BYTE_CONNECTION_ID
, !kIncludeVersion
,
288 PACKET_6BYTE_SEQUENCE_NUMBER
, 0u, NOT_IN_FEC_GROUP
);
289 QuicConnectionPeer::GetPacketCreator(connection_
)->set_max_packet_length(
292 // Write first data onto stream, which will cause one session write.
293 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MAY_FEC_PROTECT
, _
)).WillOnce(
294 Return(QuicConsumedData(kDataLen
- 1, false)));
295 stream_
->WriteOrBufferData(kData1
, false, NULL
);
296 EXPECT_TRUE(HasWriteBlockedStreams());
298 // Queue a bytes_consumed write.
299 stream_
->WriteOrBufferData(kData2
, false, NULL
);
301 // Make sure we get the tail of the first write followed by the bytes_consumed
303 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MAY_FEC_PROTECT
, _
)).
304 WillOnce(Return(QuicConsumedData(1, false)));
305 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MAY_FEC_PROTECT
, _
)).
306 WillOnce(Return(QuicConsumedData(kDataLen
- 2, false)));
307 stream_
->OnCanWrite();
309 // And finally the end of the bytes_consumed.
310 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MAY_FEC_PROTECT
, _
)).
311 WillOnce(Return(QuicConsumedData(2, true)));
312 stream_
->OnCanWrite();
315 TEST_F(ReliableQuicStreamTest
, ConnectionCloseAfterStreamClose
) {
316 Initialize(kShouldProcessData
);
318 stream_
->CloseReadSide();
319 stream_
->CloseWriteSide();
320 EXPECT_EQ(QUIC_STREAM_NO_ERROR
, stream_
->stream_error());
321 EXPECT_EQ(QUIC_NO_ERROR
, stream_
->connection_error());
322 stream_
->OnConnectionClosed(QUIC_INTERNAL_ERROR
, false);
323 EXPECT_EQ(QUIC_STREAM_NO_ERROR
, stream_
->stream_error());
324 EXPECT_EQ(QUIC_NO_ERROR
, stream_
->connection_error());
327 TEST_F(ReliableQuicStreamTest
, RstAlwaysSentIfNoFinSent
) {
328 // For flow control accounting, a stream must send either a FIN or a RST frame
329 // before termination.
330 // Test that if no FIN has been sent, we send a RST.
332 Initialize(kShouldProcessData
);
333 EXPECT_FALSE(fin_sent());
334 EXPECT_FALSE(rst_sent());
336 // Write some data, with no FIN.
337 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
338 .WillOnce(Return(QuicConsumedData(1, false)));
339 stream_
->WriteOrBufferData(StringPiece(kData1
, 1), false, NULL
);
340 EXPECT_FALSE(fin_sent());
341 EXPECT_FALSE(rst_sent());
343 // Now close the stream, and expect that we send a RST.
344 EXPECT_CALL(*session_
, SendRstStream(_
, _
, _
));
346 EXPECT_FALSE(fin_sent());
347 EXPECT_TRUE(rst_sent());
350 TEST_F(ReliableQuicStreamTest
, RstNotSentIfFinSent
) {
351 // For flow control accounting, a stream must send either a FIN or a RST frame
352 // before termination.
353 // Test that if a FIN has been sent, we don't also send a RST.
355 Initialize(kShouldProcessData
);
356 EXPECT_FALSE(fin_sent());
357 EXPECT_FALSE(rst_sent());
359 // Write some data, with FIN.
360 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
361 .WillOnce(Return(QuicConsumedData(1, true)));
362 stream_
->WriteOrBufferData(StringPiece(kData1
, 1), true, NULL
);
363 EXPECT_TRUE(fin_sent());
364 EXPECT_FALSE(rst_sent());
366 // Now close the stream, and expect that we do not send a RST.
368 EXPECT_TRUE(fin_sent());
369 EXPECT_FALSE(rst_sent());
372 TEST_F(ReliableQuicStreamTest
, OnlySendOneRst
) {
373 // For flow control accounting, a stream must send either a FIN or a RST frame
374 // before termination.
375 // Test that if a stream sends a RST, it doesn't send an additional RST during
376 // OnClose() (this shouldn't be harmful, but we shouldn't do it anyway...)
378 Initialize(kShouldProcessData
);
379 EXPECT_FALSE(fin_sent());
380 EXPECT_FALSE(rst_sent());
383 const int expected_resets
= 1;
384 EXPECT_CALL(*session_
, SendRstStream(_
, _
, _
)).Times(expected_resets
);
385 stream_
->Reset(QUIC_STREAM_CANCELLED
);
386 EXPECT_FALSE(fin_sent());
387 EXPECT_TRUE(rst_sent());
389 // Now close the stream (any further resets being sent would break the
390 // expectation above).
392 EXPECT_FALSE(fin_sent());
393 EXPECT_TRUE(rst_sent());
396 TEST_F(ReliableQuicStreamTest
, StreamFlowControlMultipleWindowUpdates
) {
397 set_initial_flow_control_window_bytes(1000);
399 Initialize(kShouldProcessData
);
401 // If we receive multiple WINDOW_UPDATES (potentially out of order), then we
402 // want to make sure we latch the largest offset we see.
404 // Initially should be default.
406 initial_flow_control_window_bytes_
,
407 QuicFlowControllerPeer::SendWindowOffset(stream_
->flow_controller()));
409 // Check a single WINDOW_UPDATE results in correct offset.
410 QuicWindowUpdateFrame
window_update_1(stream_
->id(), 1234);
411 stream_
->OnWindowUpdateFrame(window_update_1
);
413 window_update_1
.byte_offset
,
414 QuicFlowControllerPeer::SendWindowOffset(stream_
->flow_controller()));
416 // Now send a few more WINDOW_UPDATES and make sure that only the largest is
418 QuicWindowUpdateFrame
window_update_2(stream_
->id(), 1);
419 QuicWindowUpdateFrame
window_update_3(stream_
->id(), 9999);
420 QuicWindowUpdateFrame
window_update_4(stream_
->id(), 5678);
421 stream_
->OnWindowUpdateFrame(window_update_2
);
422 stream_
->OnWindowUpdateFrame(window_update_3
);
423 stream_
->OnWindowUpdateFrame(window_update_4
);
425 window_update_3
.byte_offset
,
426 QuicFlowControllerPeer::SendWindowOffset(stream_
->flow_controller()));
429 TEST_F(ReliableQuicStreamTest
, StreamFlowControlShouldNotBlockInLessThanQ017
) {
430 // TODO(rjshade): Remove this test when we no longer have any versions <
433 // Make sure we are using a version which does not support flow control.
434 QuicVersion kTestQuicVersions
[] = {QUIC_VERSION_16
};
435 QuicVersionVector versions
;
436 for (size_t i
= 0; i
< arraysize(kTestQuicVersions
); ++i
) {
437 versions
.push_back(kTestQuicVersions
[i
]);
439 set_supported_versions(versions
);
441 // Peer is not talking QUIC_VERSION_17 so assumes that it can send a zero
442 // length flow control receive window with no consequences.
443 set_initial_flow_control_window_bytes(0);
445 Initialize(kShouldProcessData
);
447 // The stream should _not_ be flow control blocked, because we are not talking
448 // a version which has flow control enabled.
449 EXPECT_FALSE(stream_
->flow_controller()->IsBlocked());
452 void SaveProxyAckNotifierDelegate(
453 scoped_refptr
<QuicAckNotifier::DelegateInterface
>* delegate_out
,
454 QuicAckNotifier::DelegateInterface
* delegate
) {
455 *delegate_out
= delegate
;
458 TEST_F(ReliableQuicStreamTest
, WriteOrBufferDataWithQuicAckNotifier
) {
459 Initialize(kShouldProcessData
);
461 scoped_refptr
<MockAckNotifierDelegate
> delegate(
462 new StrictMock
<MockAckNotifierDelegate
>);
464 const int kDataSize
= 16 * 1024;
465 const string
kData(kDataSize
, 'a');
467 const int kFirstWriteSize
= 100;
468 const int kSecondWriteSize
= 50;
469 const int kLastWriteSize
= kDataSize
- kFirstWriteSize
- kSecondWriteSize
;
471 // Set a large flow control send window so this doesn't interfere with test.
472 stream_
->flow_controller()->UpdateSendWindowOffset(kDataSize
+ 1);
473 session_
->flow_controller()->UpdateSendWindowOffset(kDataSize
+ 1);
475 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
477 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
478 .WillOnce(DoAll(WithArgs
<5>(Invoke(CreateFunctor(
479 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
480 Return(QuicConsumedData(kFirstWriteSize
, false))));
481 stream_
->WriteOrBufferData(kData
, false, delegate
.get());
482 EXPECT_TRUE(HasWriteBlockedStreams());
484 EXPECT_CALL(*session_
,
485 WritevData(kHeadersStreamId
, _
, _
, _
, _
, proxy_delegate
.get()))
486 .WillOnce(Return(QuicConsumedData(kSecondWriteSize
, false)));
487 stream_
->OnCanWrite();
489 // No ack expected for an empty write.
490 EXPECT_CALL(*session_
,
491 WritevData(kHeadersStreamId
, _
, _
, _
, _
, proxy_delegate
.get()))
492 .WillOnce(Return(QuicConsumedData(0, false)));
493 stream_
->OnCanWrite();
495 EXPECT_CALL(*session_
,
496 WritevData(kHeadersStreamId
, _
, _
, _
, _
, proxy_delegate
.get()))
497 .WillOnce(Return(QuicConsumedData(kLastWriteSize
, false)));
498 stream_
->OnCanWrite();
500 // There were two writes, so OnAckNotification is not propagated
501 // until the third Ack arrives.
502 proxy_delegate
->OnAckNotification(1, 2, 3, 4, zero_
);
503 proxy_delegate
->OnAckNotification(10, 20, 30, 40, zero_
);
505 // The arguments to delegate->OnAckNotification are the sum of the
506 // arguments to proxy_delegate OnAckNotification calls.
507 EXPECT_CALL(*delegate
.get(), OnAckNotification(111, 222, 333, 444, zero_
));
508 proxy_delegate
->OnAckNotification(100, 200, 300, 400, zero_
);
511 // Verify delegate behavior when packets are acked before the
512 // WritevData call that sends out the last byte.
513 TEST_F(ReliableQuicStreamTest
, WriteOrBufferDataAckNotificationBeforeFlush
) {
514 Initialize(kShouldProcessData
);
516 scoped_refptr
<MockAckNotifierDelegate
> delegate(
517 new StrictMock
<MockAckNotifierDelegate
>);
519 const int kDataSize
= 16 * 1024;
520 const string
kData(kDataSize
, 'a');
522 const int kInitialWriteSize
= 100;
524 // Set a large flow control send window so this doesn't interfere with test.
525 stream_
->flow_controller()->UpdateSendWindowOffset(kDataSize
+ 1);
526 session_
->flow_controller()->UpdateSendWindowOffset(kDataSize
+ 1);
528 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
530 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
531 .WillOnce(DoAll(WithArgs
<5>(Invoke(CreateFunctor(
532 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
533 Return(QuicConsumedData(kInitialWriteSize
, false))));
534 stream_
->WriteOrBufferData(kData
, false, delegate
.get());
535 EXPECT_TRUE(HasWriteBlockedStreams());
537 // Handle the ack of the first write.
538 proxy_delegate
->OnAckNotification(1, 2, 3, 4, zero_
);
539 proxy_delegate
= NULL
;
541 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
)).WillOnce(
542 DoAll(WithArgs
<5>(Invoke(CreateFunctor(
543 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
544 Return(QuicConsumedData(kDataSize
- kInitialWriteSize
, false))));
545 stream_
->OnCanWrite();
547 // Handle the ack for the second write.
548 EXPECT_CALL(*delegate
.get(), OnAckNotification(101, 202, 303, 404, zero_
));
549 proxy_delegate
->OnAckNotification(100, 200, 300, 400, zero_
);
552 // Verify delegate behavior when WriteOrBufferData does not buffer.
553 TEST_F(ReliableQuicStreamTest
, WriteAndBufferDataWithAckNotiferNoBuffer
) {
554 Initialize(kShouldProcessData
);
556 scoped_refptr
<MockAckNotifierDelegate
> delegate(
557 new StrictMock
<MockAckNotifierDelegate
>);
559 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
561 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
562 .WillOnce(DoAll(WithArgs
<5>(Invoke(CreateFunctor(
563 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
564 Return(QuicConsumedData(kDataLen
, true))));
565 stream_
->WriteOrBufferData(kData1
, true, delegate
.get());
566 EXPECT_FALSE(HasWriteBlockedStreams());
569 EXPECT_CALL(*delegate
.get(), OnAckNotification(1, 2, 3, 4, zero_
));
570 proxy_delegate
->OnAckNotification(1, 2, 3, 4, zero_
);
573 // Verify delegate behavior when WriteOrBufferData buffers all the data.
574 TEST_F(ReliableQuicStreamTest
, BufferOnWriteAndBufferDataWithAckNotifer
) {
575 Initialize(kShouldProcessData
);
577 scoped_refptr
<MockAckNotifierDelegate
> delegate(
578 new StrictMock
<MockAckNotifierDelegate
>);
580 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
582 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
583 .WillOnce(Return(QuicConsumedData(0, false)));
584 stream_
->WriteOrBufferData(kData1
, true, delegate
.get());
585 EXPECT_TRUE(HasWriteBlockedStreams());
587 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
588 .WillOnce(DoAll(WithArgs
<5>(Invoke(CreateFunctor(
589 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
590 Return(QuicConsumedData(kDataLen
, true))));
591 stream_
->OnCanWrite();
594 EXPECT_CALL(*delegate
.get(), OnAckNotification(1, 2, 3, 4, zero_
));
595 proxy_delegate
->OnAckNotification(1, 2, 3, 4, zero_
);
598 // Verify delegate behavior when WriteOrBufferData when the FIN is
599 // sent out in a different packet.
600 TEST_F(ReliableQuicStreamTest
, WriteAndBufferDataWithAckNotiferOnlyFinRemains
) {
601 Initialize(kShouldProcessData
);
603 scoped_refptr
<MockAckNotifierDelegate
> delegate(
604 new StrictMock
<MockAckNotifierDelegate
>);
606 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
608 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
609 .WillOnce(DoAll(WithArgs
<5>(Invoke(CreateFunctor(
610 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
611 Return(QuicConsumedData(kDataLen
, false))));
612 stream_
->WriteOrBufferData(kData1
, true, delegate
.get());
613 EXPECT_TRUE(HasWriteBlockedStreams());
615 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
616 .WillOnce(DoAll(WithArgs
<5>(Invoke(CreateFunctor(
617 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
618 Return(QuicConsumedData(0, true))));
619 stream_
->OnCanWrite();
622 proxy_delegate
->OnAckNotification(1, 2, 3, 4, zero_
);
623 EXPECT_CALL(*delegate
.get(), OnAckNotification(11, 22, 33, 44, zero_
));
624 proxy_delegate
->OnAckNotification(10, 20, 30, 40, zero_
);
627 // Verify that when we receive a packet which violates flow control (i.e. sends
628 // too much data on the stream) that the stream sequencer never sees this frame,
629 // as we check for violation and close the connection early.
630 TEST_F(ReliableQuicStreamTest
,
631 StreamSequencerNeverSeesPacketsViolatingFlowControl
) {
632 Initialize(kShouldProcessData
);
634 // Receive a stream frame that violates flow control: the byte offset is
635 // higher than the receive window offset.
636 QuicStreamFrame
frame(stream_
->id(), false,
637 kInitialSessionFlowControlWindowForTest
+ 1,
639 EXPECT_GT(frame
.offset
, QuicFlowControllerPeer::ReceiveWindowOffset(
640 stream_
->flow_controller()));
642 // Stream should not accept the frame, and the connection should be closed.
643 EXPECT_CALL(*connection_
,
644 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA
));
645 stream_
->OnStreamFrame(frame
);
648 TEST_F(ReliableQuicStreamTest
, FinalByteOffsetFromFin
) {
649 Initialize(kShouldProcessData
);
651 EXPECT_FALSE(stream_
->HasFinalReceivedByteOffset());
653 QuicStreamFrame
stream_frame_no_fin(stream_
->id(), false, 1234,
655 stream_
->OnStreamFrame(stream_frame_no_fin
);
656 EXPECT_FALSE(stream_
->HasFinalReceivedByteOffset());
658 QuicStreamFrame
stream_frame_with_fin(stream_
->id(), true, 1234,
660 stream_
->OnStreamFrame(stream_frame_with_fin
);
661 EXPECT_TRUE(stream_
->HasFinalReceivedByteOffset());
664 TEST_F(ReliableQuicStreamTest
, FinalByteOffsetFromRst
) {
665 Initialize(kShouldProcessData
);
667 EXPECT_FALSE(stream_
->HasFinalReceivedByteOffset());
668 QuicRstStreamFrame
rst_frame(stream_
->id(), QUIC_STREAM_CANCELLED
, 1234);
669 stream_
->OnStreamReset(rst_frame
);
670 EXPECT_TRUE(stream_
->HasFinalReceivedByteOffset());