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_flags.h"
10 #include "net/quic/quic_utils.h"
11 #include "net/quic/quic_write_blocked_list.h"
12 #include "net/quic/spdy_utils.h"
13 #include "net/quic/test_tools/quic_config_peer.h"
14 #include "net/quic/test_tools/quic_connection_peer.h"
15 #include "net/quic/test_tools/quic_flow_controller_peer.h"
16 #include "net/quic/test_tools/quic_session_peer.h"
17 #include "net/quic/test_tools/quic_test_utils.h"
18 #include "net/quic/test_tools/reliable_quic_stream_peer.h"
19 #include "net/test/gtest_util.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gmock_mutant.h"
23 using base::StringPiece
;
25 using testing::CreateFunctor
;
26 using testing::InSequence
;
27 using testing::Invoke
;
28 using testing::Return
;
29 using testing::SaveArg
;
30 using testing::StrictMock
;
31 using testing::WithArgs
;
38 const char kData1
[] = "FooAndBar";
39 const char kData2
[] = "EepAndBaz";
40 const size_t kDataLen
= 9;
41 const bool kIsServer
= true;
42 const bool kShouldProcessData
= true;
44 class TestStream
: public ReliableQuicStream
{
46 TestStream(QuicStreamId id
,
48 bool should_process_data
)
49 : ReliableQuicStream(id
, session
),
50 should_process_data_(should_process_data
) {}
52 virtual uint32
ProcessRawData(const char* data
, uint32 data_len
) OVERRIDE
{
53 EXPECT_NE(0u, data_len
);
54 DVLOG(1) << "ProcessData data_len: " << data_len
;
55 data_
+= string(data
, data_len
);
56 return should_process_data_
? data_len
: 0;
59 virtual QuicPriority
EffectivePriority() const OVERRIDE
{
60 return QuicUtils::HighestPriority();
63 using ReliableQuicStream::WriteOrBufferData
;
64 using ReliableQuicStream::CloseReadSide
;
65 using ReliableQuicStream::CloseWriteSide
;
66 using ReliableQuicStream::OnClose
;
69 bool should_process_data_
;
73 class ReliableQuicStreamTest
: public ::testing::TestWithParam
<bool> {
75 ReliableQuicStreamTest()
76 : initial_flow_control_window_bytes_(kMaxPacketSize
),
77 zero_(QuicTime::Delta::Zero()),
78 supported_versions_(QuicSupportedVersions()) {
79 headers_
[":host"] = "www.google.com";
80 headers_
[":path"] = "/index.hml";
81 headers_
[":scheme"] = "https";
83 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
85 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
86 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
87 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
88 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
89 "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
90 "1zFMi5vzcns38-8_Sns; "
91 "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
92 "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
93 "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
94 "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
95 "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
96 "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
97 "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
98 "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
99 "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
100 "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
101 "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
102 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
103 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
104 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
105 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
108 void set_supported_versions(const QuicVersionVector
& versions
) {
109 supported_versions_
= versions
;
112 void Initialize(bool stream_should_process_data
) {
114 new StrictMock
<MockConnection
>(kIsServer
, supported_versions_
);
115 session_
.reset(new StrictMock
<MockSession
>(connection_
));
117 // New streams rely on having the peer's flow control receive window
118 // negotiated in the config.
119 QuicConfigPeer::SetReceivedInitialFlowControlWindow(
120 session_
->config(), initial_flow_control_window_bytes_
);
121 QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(
122 session_
->config(), initial_flow_control_window_bytes_
);
124 stream_
.reset(new TestStream(kHeadersStreamId
, session_
.get(),
125 stream_should_process_data
));
126 write_blocked_list_
=
127 QuicSessionPeer::GetWriteBlockedStreams(session_
.get());
130 bool fin_sent() { return ReliableQuicStreamPeer::FinSent(stream_
.get()); }
131 bool rst_sent() { return ReliableQuicStreamPeer::RstSent(stream_
.get()); }
133 void set_initial_flow_control_window_bytes(uint32 val
) {
134 initial_flow_control_window_bytes_
= val
;
137 bool HasWriteBlockedStreams() {
138 return write_blocked_list_
->HasWriteBlockedCryptoOrHeadersStream() ||
139 write_blocked_list_
->HasWriteBlockedDataStreams();
143 MockConnection
* connection_
;
144 scoped_ptr
<MockSession
> session_
;
145 scoped_ptr
<TestStream
> stream_
;
146 SpdyHeaderBlock headers_
;
147 QuicWriteBlockedList
* write_blocked_list_
;
148 uint32 initial_flow_control_window_bytes_
;
149 QuicTime::Delta zero_
;
150 QuicVersionVector supported_versions_
;
153 TEST_F(ReliableQuicStreamTest
, WriteAllData
) {
154 Initialize(kShouldProcessData
);
156 size_t length
= 1 + QuicPacketCreator::StreamFramePacketOverhead(
157 connection_
->version(), PACKET_8BYTE_CONNECTION_ID
, !kIncludeVersion
,
158 PACKET_6BYTE_SEQUENCE_NUMBER
, 0u, NOT_IN_FEC_GROUP
);
159 QuicConnectionPeer::GetPacketCreator(connection_
)->set_max_packet_length(
162 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
)).WillOnce(
163 Return(QuicConsumedData(kDataLen
, true)));
164 stream_
->WriteOrBufferData(kData1
, false, NULL
);
165 EXPECT_FALSE(HasWriteBlockedStreams());
168 TEST_F(ReliableQuicStreamTest
, NoBlockingIfNoDataOrFin
) {
169 Initialize(kShouldProcessData
);
171 // Write no data and no fin. If we consume nothing we should not be write
173 EXPECT_DFATAL(stream_
->WriteOrBufferData(StringPiece(), false, NULL
), "");
174 EXPECT_FALSE(HasWriteBlockedStreams());
177 TEST_F(ReliableQuicStreamTest
, BlockIfOnlySomeDataConsumed
) {
178 Initialize(kShouldProcessData
);
180 // Write some data and no fin. If we consume some but not all of the data,
181 // we should be write blocked a not all the data was consumed.
182 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
183 .WillOnce(Return(QuicConsumedData(1, false)));
184 stream_
->WriteOrBufferData(StringPiece(kData1
, 2), false, NULL
);
185 ASSERT_EQ(1u, write_blocked_list_
->NumBlockedStreams());
188 TEST_F(ReliableQuicStreamTest
, BlockIfFinNotConsumedWithData
) {
189 Initialize(kShouldProcessData
);
191 // Write some data and no fin. If we consume all the data but not the fin,
192 // we should be write blocked because the fin was not consumed.
193 // (This should never actually happen as the fin should be sent out with the
195 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
196 .WillOnce(Return(QuicConsumedData(2, false)));
197 stream_
->WriteOrBufferData(StringPiece(kData1
, 2), true, NULL
);
198 ASSERT_EQ(1u, write_blocked_list_
->NumBlockedStreams());
201 TEST_F(ReliableQuicStreamTest
, BlockIfSoloFinNotConsumed
) {
202 Initialize(kShouldProcessData
);
204 // Write no data and a fin. If we consume nothing we should be write blocked,
205 // as the fin was not consumed.
206 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
207 .WillOnce(Return(QuicConsumedData(0, false)));
208 stream_
->WriteOrBufferData(StringPiece(), true, NULL
);
209 ASSERT_EQ(1u, write_blocked_list_
->NumBlockedStreams());
212 TEST_F(ReliableQuicStreamTest
, WriteOrBufferData
) {
213 Initialize(kShouldProcessData
);
215 EXPECT_FALSE(HasWriteBlockedStreams());
216 size_t length
= 1 + QuicPacketCreator::StreamFramePacketOverhead(
217 connection_
->version(), PACKET_8BYTE_CONNECTION_ID
, !kIncludeVersion
,
218 PACKET_6BYTE_SEQUENCE_NUMBER
, 0u, NOT_IN_FEC_GROUP
);
219 QuicConnectionPeer::GetPacketCreator(connection_
)->set_max_packet_length(
222 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, _
, _
)).WillOnce(
223 Return(QuicConsumedData(kDataLen
- 1, false)));
224 stream_
->WriteOrBufferData(kData1
, false, NULL
);
225 EXPECT_TRUE(HasWriteBlockedStreams());
227 // Queue a bytes_consumed write.
228 stream_
->WriteOrBufferData(kData2
, false, NULL
);
230 // Make sure we get the tail of the first write followed by the bytes_consumed
232 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, _
, _
)).
233 WillOnce(Return(QuicConsumedData(1, false)));
234 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, _
, _
)).
235 WillOnce(Return(QuicConsumedData(kDataLen
- 2, false)));
236 stream_
->OnCanWrite();
238 // And finally the end of the bytes_consumed.
239 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, _
, _
)).
240 WillOnce(Return(QuicConsumedData(2, true)));
241 stream_
->OnCanWrite();
244 TEST_F(ReliableQuicStreamTest
, WriteOrBufferDataWithFecProtectAlways
) {
245 Initialize(kShouldProcessData
);
247 // Set FEC policy on stream.
248 ReliableQuicStreamPeer::SetFecPolicy(stream_
.get(), FEC_PROTECT_ALWAYS
);
250 EXPECT_FALSE(HasWriteBlockedStreams());
251 size_t length
= 1 + QuicPacketCreator::StreamFramePacketOverhead(
252 connection_
->version(), PACKET_8BYTE_CONNECTION_ID
, !kIncludeVersion
,
253 PACKET_6BYTE_SEQUENCE_NUMBER
, 0u, IN_FEC_GROUP
);
254 QuicConnectionPeer::GetPacketCreator(connection_
)->set_max_packet_length(
257 // Write first data onto stream, which will cause one session write.
258 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MUST_FEC_PROTECT
, _
)).WillOnce(
259 Return(QuicConsumedData(kDataLen
- 1, false)));
260 stream_
->WriteOrBufferData(kData1
, false, NULL
);
261 EXPECT_TRUE(HasWriteBlockedStreams());
263 // Queue a bytes_consumed write.
264 stream_
->WriteOrBufferData(kData2
, false, NULL
);
266 // Make sure we get the tail of the first write followed by the bytes_consumed
268 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MUST_FEC_PROTECT
, _
)).
269 WillOnce(Return(QuicConsumedData(1, false)));
270 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MUST_FEC_PROTECT
, _
)).
271 WillOnce(Return(QuicConsumedData(kDataLen
- 2, false)));
272 stream_
->OnCanWrite();
274 // And finally the end of the bytes_consumed.
275 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MUST_FEC_PROTECT
, _
)).
276 WillOnce(Return(QuicConsumedData(2, true)));
277 stream_
->OnCanWrite();
280 TEST_F(ReliableQuicStreamTest
, WriteOrBufferDataWithFecProtectOptional
) {
281 Initialize(kShouldProcessData
);
283 // Set FEC policy on stream.
284 ReliableQuicStreamPeer::SetFecPolicy(stream_
.get(), FEC_PROTECT_OPTIONAL
);
286 EXPECT_FALSE(HasWriteBlockedStreams());
287 size_t length
= 1 + QuicPacketCreator::StreamFramePacketOverhead(
288 connection_
->version(), PACKET_8BYTE_CONNECTION_ID
, !kIncludeVersion
,
289 PACKET_6BYTE_SEQUENCE_NUMBER
, 0u, NOT_IN_FEC_GROUP
);
290 QuicConnectionPeer::GetPacketCreator(connection_
)->set_max_packet_length(
293 // Write first data onto stream, which will cause one session write.
294 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MAY_FEC_PROTECT
, _
)).WillOnce(
295 Return(QuicConsumedData(kDataLen
- 1, false)));
296 stream_
->WriteOrBufferData(kData1
, false, NULL
);
297 EXPECT_TRUE(HasWriteBlockedStreams());
299 // Queue a bytes_consumed write.
300 stream_
->WriteOrBufferData(kData2
, false, NULL
);
302 // Make sure we get the tail of the first write followed by the bytes_consumed
304 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MAY_FEC_PROTECT
, _
)).
305 WillOnce(Return(QuicConsumedData(1, false)));
306 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MAY_FEC_PROTECT
, _
)).
307 WillOnce(Return(QuicConsumedData(kDataLen
- 2, false)));
308 stream_
->OnCanWrite();
310 // And finally the end of the bytes_consumed.
311 EXPECT_CALL(*session_
, WritevData(_
, _
, _
, _
, MAY_FEC_PROTECT
, _
)).
312 WillOnce(Return(QuicConsumedData(2, true)));
313 stream_
->OnCanWrite();
316 TEST_F(ReliableQuicStreamTest
, ConnectionCloseAfterStreamClose
) {
317 Initialize(kShouldProcessData
);
319 stream_
->CloseReadSide();
320 stream_
->CloseWriteSide();
321 EXPECT_EQ(QUIC_STREAM_NO_ERROR
, stream_
->stream_error());
322 EXPECT_EQ(QUIC_NO_ERROR
, stream_
->connection_error());
323 stream_
->OnConnectionClosed(QUIC_INTERNAL_ERROR
, false);
324 EXPECT_EQ(QUIC_STREAM_NO_ERROR
, stream_
->stream_error());
325 EXPECT_EQ(QUIC_NO_ERROR
, stream_
->connection_error());
328 TEST_F(ReliableQuicStreamTest
, RstAlwaysSentIfNoFinSent
) {
329 // For flow control accounting, a stream must send either a FIN or a RST frame
330 // before termination.
331 // Test that if no FIN has been sent, we send a RST.
333 Initialize(kShouldProcessData
);
334 EXPECT_FALSE(fin_sent());
335 EXPECT_FALSE(rst_sent());
337 // Write some data, with no FIN.
338 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
339 .WillOnce(Return(QuicConsumedData(1, false)));
340 stream_
->WriteOrBufferData(StringPiece(kData1
, 1), false, NULL
);
341 EXPECT_FALSE(fin_sent());
342 EXPECT_FALSE(rst_sent());
344 // Now close the stream, and expect that we send a RST.
345 EXPECT_CALL(*session_
, SendRstStream(_
, _
, _
));
347 EXPECT_FALSE(fin_sent());
348 EXPECT_TRUE(rst_sent());
351 TEST_F(ReliableQuicStreamTest
, RstNotSentIfFinSent
) {
352 // For flow control accounting, a stream must send either a FIN or a RST frame
353 // before termination.
354 // Test that if a FIN has been sent, we don't also send a RST.
356 Initialize(kShouldProcessData
);
357 EXPECT_FALSE(fin_sent());
358 EXPECT_FALSE(rst_sent());
360 // Write some data, with FIN.
361 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
362 .WillOnce(Return(QuicConsumedData(1, true)));
363 stream_
->WriteOrBufferData(StringPiece(kData1
, 1), true, NULL
);
364 EXPECT_TRUE(fin_sent());
365 EXPECT_FALSE(rst_sent());
367 // Now close the stream, and expect that we do not send a RST.
369 EXPECT_TRUE(fin_sent());
370 EXPECT_FALSE(rst_sent());
373 TEST_F(ReliableQuicStreamTest
, OnlySendOneRst
) {
374 // For flow control accounting, a stream must send either a FIN or a RST frame
375 // before termination.
376 // Test that if a stream sends a RST, it doesn't send an additional RST during
377 // OnClose() (this shouldn't be harmful, but we shouldn't do it anyway...)
379 Initialize(kShouldProcessData
);
380 EXPECT_FALSE(fin_sent());
381 EXPECT_FALSE(rst_sent());
384 const int expected_resets
= 1;
385 EXPECT_CALL(*session_
, SendRstStream(_
, _
, _
)).Times(expected_resets
);
386 stream_
->Reset(QUIC_STREAM_CANCELLED
);
387 EXPECT_FALSE(fin_sent());
388 EXPECT_TRUE(rst_sent());
390 // Now close the stream (any further resets being sent would break the
391 // expectation above).
393 EXPECT_FALSE(fin_sent());
394 EXPECT_TRUE(rst_sent());
397 TEST_F(ReliableQuicStreamTest
, StreamFlowControlMultipleWindowUpdates
) {
398 set_initial_flow_control_window_bytes(1000);
400 Initialize(kShouldProcessData
);
402 // If we receive multiple WINDOW_UPDATES (potentially out of order), then we
403 // want to make sure we latch the largest offset we see.
405 // Initially should be default.
407 initial_flow_control_window_bytes_
,
408 QuicFlowControllerPeer::SendWindowOffset(stream_
->flow_controller()));
410 // Check a single WINDOW_UPDATE results in correct offset.
411 QuicWindowUpdateFrame
window_update_1(stream_
->id(), 1234);
412 stream_
->OnWindowUpdateFrame(window_update_1
);
414 window_update_1
.byte_offset
,
415 QuicFlowControllerPeer::SendWindowOffset(stream_
->flow_controller()));
417 // Now send a few more WINDOW_UPDATES and make sure that only the largest is
419 QuicWindowUpdateFrame
window_update_2(stream_
->id(), 1);
420 QuicWindowUpdateFrame
window_update_3(stream_
->id(), 9999);
421 QuicWindowUpdateFrame
window_update_4(stream_
->id(), 5678);
422 stream_
->OnWindowUpdateFrame(window_update_2
);
423 stream_
->OnWindowUpdateFrame(window_update_3
);
424 stream_
->OnWindowUpdateFrame(window_update_4
);
426 window_update_3
.byte_offset
,
427 QuicFlowControllerPeer::SendWindowOffset(stream_
->flow_controller()));
430 TEST_F(ReliableQuicStreamTest
, StreamFlowControlShouldNotBlockInLessThanQ017
) {
431 // TODO(rjshade): Remove this test when we no longer have any versions <
434 // Make sure we are using a version which does not support flow control.
435 QuicVersion kTestQuicVersions
[] = {QUIC_VERSION_16
};
436 QuicVersionVector versions
;
437 for (size_t i
= 0; i
< arraysize(kTestQuicVersions
); ++i
) {
438 versions
.push_back(kTestQuicVersions
[i
]);
440 set_supported_versions(versions
);
442 // Peer is not talking QUIC_VERSION_17 so assumes that it can send a zero
443 // length flow control receive window with no consequences.
444 set_initial_flow_control_window_bytes(0);
446 Initialize(kShouldProcessData
);
448 // The stream should _not_ be flow control blocked, because we are not talking
449 // a version which has flow control enabled.
450 EXPECT_FALSE(stream_
->flow_controller()->IsBlocked());
453 void SaveProxyAckNotifierDelegate(
454 scoped_refptr
<QuicAckNotifier::DelegateInterface
>* delegate_out
,
455 QuicAckNotifier::DelegateInterface
* delegate
) {
456 *delegate_out
= delegate
;
459 TEST_F(ReliableQuicStreamTest
, WriteOrBufferDataWithQuicAckNotifier
) {
460 Initialize(kShouldProcessData
);
462 scoped_refptr
<MockAckNotifierDelegate
> delegate(
463 new StrictMock
<MockAckNotifierDelegate
>);
465 const int kDataSize
= 16 * 1024;
466 const string
kData(kDataSize
, 'a');
468 const int kFirstWriteSize
= 100;
469 const int kSecondWriteSize
= 50;
470 const int kLastWriteSize
= kDataSize
- kFirstWriteSize
- kSecondWriteSize
;
472 // Set a large flow control send window so this doesn't interfere with test.
473 stream_
->flow_controller()->UpdateSendWindowOffset(kDataSize
+ 1);
474 if (FLAGS_enable_quic_connection_flow_control_2
) {
475 session_
->flow_controller()->UpdateSendWindowOffset(kDataSize
+ 1);
478 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
480 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
481 .WillOnce(DoAll(WithArgs
<5>(Invoke(CreateFunctor(
482 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
483 Return(QuicConsumedData(kFirstWriteSize
, false))));
484 stream_
->WriteOrBufferData(kData
, false, delegate
.get());
485 EXPECT_TRUE(HasWriteBlockedStreams());
487 EXPECT_CALL(*session_
,
488 WritevData(kHeadersStreamId
, _
, _
, _
, _
, proxy_delegate
.get()))
489 .WillOnce(Return(QuicConsumedData(kSecondWriteSize
, false)));
490 stream_
->OnCanWrite();
492 // No ack expected for an empty write.
493 EXPECT_CALL(*session_
,
494 WritevData(kHeadersStreamId
, _
, _
, _
, _
, proxy_delegate
.get()))
495 .WillOnce(Return(QuicConsumedData(0, false)));
496 stream_
->OnCanWrite();
498 EXPECT_CALL(*session_
,
499 WritevData(kHeadersStreamId
, _
, _
, _
, _
, proxy_delegate
.get()))
500 .WillOnce(Return(QuicConsumedData(kLastWriteSize
, false)));
501 stream_
->OnCanWrite();
503 // There were two writes, so OnAckNotification is not propagated
504 // until the third Ack arrives.
505 proxy_delegate
->OnAckNotification(1, 2, 3, 4, zero_
);
506 proxy_delegate
->OnAckNotification(10, 20, 30, 40, zero_
);
508 // The arguments to delegate->OnAckNotification are the sum of the
509 // arguments to proxy_delegate OnAckNotification calls.
510 EXPECT_CALL(*delegate
, OnAckNotification(111, 222, 333, 444, zero_
));
511 proxy_delegate
->OnAckNotification(100, 200, 300, 400, zero_
);
514 // Verify delegate behavior when packets are acked before the
515 // WritevData call that sends out the last byte.
516 TEST_F(ReliableQuicStreamTest
, WriteOrBufferDataAckNotificationBeforeFlush
) {
517 Initialize(kShouldProcessData
);
519 scoped_refptr
<MockAckNotifierDelegate
> delegate(
520 new StrictMock
<MockAckNotifierDelegate
>);
522 const int kDataSize
= 16 * 1024;
523 const string
kData(kDataSize
, 'a');
525 const int kInitialWriteSize
= 100;
527 // Set a large flow control send window so this doesn't interfere with test.
528 stream_
->flow_controller()->UpdateSendWindowOffset(kDataSize
+ 1);
529 if (FLAGS_enable_quic_connection_flow_control_2
) {
530 session_
->flow_controller()->UpdateSendWindowOffset(kDataSize
+ 1);
533 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
535 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
536 .WillOnce(DoAll(WithArgs
<5>(Invoke(CreateFunctor(
537 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
538 Return(QuicConsumedData(kInitialWriteSize
, false))));
539 stream_
->WriteOrBufferData(kData
, false, delegate
.get());
540 EXPECT_TRUE(HasWriteBlockedStreams());
542 // Handle the ack of the first write.
543 proxy_delegate
->OnAckNotification(1, 2, 3, 4, zero_
);
544 proxy_delegate
= NULL
;
546 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
)).WillOnce(
547 DoAll(WithArgs
<5>(Invoke(CreateFunctor(
548 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
549 Return(QuicConsumedData(kDataSize
- kInitialWriteSize
, false))));
550 stream_
->OnCanWrite();
552 // Handle the ack for the second write.
553 EXPECT_CALL(*delegate
, OnAckNotification(101, 202, 303, 404, zero_
));
554 proxy_delegate
->OnAckNotification(100, 200, 300, 400, zero_
);
557 // Verify delegate behavior when WriteOrBufferData does not buffer.
558 TEST_F(ReliableQuicStreamTest
, WriteAndBufferDataWithAckNotiferNoBuffer
) {
559 Initialize(kShouldProcessData
);
561 scoped_refptr
<MockAckNotifierDelegate
> delegate(
562 new StrictMock
<MockAckNotifierDelegate
>);
564 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
566 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
567 .WillOnce(DoAll(WithArgs
<5>(Invoke(CreateFunctor(
568 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
569 Return(QuicConsumedData(kDataLen
, true))));
570 stream_
->WriteOrBufferData(kData1
, true, delegate
.get());
571 EXPECT_FALSE(HasWriteBlockedStreams());
574 EXPECT_CALL(*delegate
, OnAckNotification(1, 2, 3, 4, zero_
));
575 proxy_delegate
->OnAckNotification(1, 2, 3, 4, zero_
);
578 // Verify delegate behavior when WriteOrBufferData buffers all the data.
579 TEST_F(ReliableQuicStreamTest
, BufferOnWriteAndBufferDataWithAckNotifer
) {
580 Initialize(kShouldProcessData
);
582 scoped_refptr
<MockAckNotifierDelegate
> delegate(
583 new StrictMock
<MockAckNotifierDelegate
>);
585 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
587 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
588 .WillOnce(Return(QuicConsumedData(0, false)));
589 stream_
->WriteOrBufferData(kData1
, true, delegate
.get());
590 EXPECT_TRUE(HasWriteBlockedStreams());
592 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
593 .WillOnce(DoAll(WithArgs
<5>(Invoke(CreateFunctor(
594 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
595 Return(QuicConsumedData(kDataLen
, true))));
596 stream_
->OnCanWrite();
599 EXPECT_CALL(*delegate
, OnAckNotification(1, 2, 3, 4, zero_
));
600 proxy_delegate
->OnAckNotification(1, 2, 3, 4, zero_
);
603 // Verify delegate behavior when WriteOrBufferData when the FIN is
604 // sent out in a different packet.
605 TEST_F(ReliableQuicStreamTest
, WriteAndBufferDataWithAckNotiferOnlyFinRemains
) {
606 Initialize(kShouldProcessData
);
608 scoped_refptr
<MockAckNotifierDelegate
> delegate(
609 new StrictMock
<MockAckNotifierDelegate
>);
611 scoped_refptr
<QuicAckNotifier::DelegateInterface
> proxy_delegate
;
613 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
614 .WillOnce(DoAll(WithArgs
<5>(Invoke(CreateFunctor(
615 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
616 Return(QuicConsumedData(kDataLen
, false))));
617 stream_
->WriteOrBufferData(kData1
, true, delegate
.get());
618 EXPECT_TRUE(HasWriteBlockedStreams());
620 EXPECT_CALL(*session_
, WritevData(kHeadersStreamId
, _
, _
, _
, _
, _
))
621 .WillOnce(DoAll(WithArgs
<5>(Invoke(CreateFunctor(
622 &SaveProxyAckNotifierDelegate
, &proxy_delegate
))),
623 Return(QuicConsumedData(0, true))));
624 stream_
->OnCanWrite();
627 proxy_delegate
->OnAckNotification(1, 2, 3, 4, zero_
);
628 EXPECT_CALL(*delegate
, OnAckNotification(11, 22, 33, 44, zero_
));
629 proxy_delegate
->OnAckNotification(10, 20, 30, 40, zero_
);
632 // Verify that when we receive a packet which violates flow control (i.e. sends
633 // too much data on the stream) that the stream sequencer never sees this frame,
634 // as we check for violation and close the connection early.
635 TEST_F(ReliableQuicStreamTest
,
636 StreamSequencerNeverSeesPacketsViolatingFlowControl
) {
637 ValueRestore
<bool> old_connection_flag(
638 &FLAGS_enable_quic_connection_flow_control_2
, true);
640 Initialize(kShouldProcessData
);
642 // Receive a stream frame that violates flow control: the byte offset is
643 // higher than the receive window offset.
644 QuicStreamFrame
frame(stream_
->id(), false,
645 kInitialSessionFlowControlWindowForTest
+ 1,
647 EXPECT_GT(frame
.offset
, QuicFlowControllerPeer::ReceiveWindowOffset(
648 stream_
->flow_controller()));
650 // Stream should not accept the frame, and the connection should be closed.
651 EXPECT_CALL(*connection_
,
652 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA
));
653 EXPECT_FALSE(stream_
->OnStreamFrame(frame
));
656 TEST_F(ReliableQuicStreamTest
, FinalByteOffsetFromFin
) {
657 Initialize(kShouldProcessData
);
659 EXPECT_FALSE(stream_
->HasFinalReceivedByteOffset());
661 QuicStreamFrame
stream_frame_no_fin(stream_
->id(), false, 1234,
663 stream_
->OnStreamFrame(stream_frame_no_fin
);
664 EXPECT_FALSE(stream_
->HasFinalReceivedByteOffset());
666 QuicStreamFrame
stream_frame_with_fin(stream_
->id(), true, 1234,
668 stream_
->OnStreamFrame(stream_frame_with_fin
);
669 EXPECT_TRUE(stream_
->HasFinalReceivedByteOffset());
672 TEST_F(ReliableQuicStreamTest
, FinalByteOffsetFromRst
) {
673 Initialize(kShouldProcessData
);
675 EXPECT_FALSE(stream_
->HasFinalReceivedByteOffset());
676 QuicRstStreamFrame
rst_frame(stream_
->id(), QUIC_STREAM_CANCELLED
, 1234);
677 stream_
->OnStreamReset(rst_frame
);
678 EXPECT_TRUE(stream_
->HasFinalReceivedByteOffset());