12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/reliable_quic_stream.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/quic/quic_ack_notifier.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_connection.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_utils.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_write_blocked_list.h" 11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/quic/spdy_utils.h" 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "net/quic/test_tools/quic_config_peer.h" 1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/quic/test_tools/quic_connection_peer.h" 140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "net/quic/test_tools/quic_flow_controller_peer.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/quic/test_tools/quic_session_peer.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/test_tools/reliable_quic_stream_peer.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/test/gtest_util.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "testing/gmock_mutant.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::StringPiece; 23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using std::min; 2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)using testing::CreateFunctor; 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::InSequence; 2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)using testing::Invoke; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Return; 28b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using testing::SaveArg; 29b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using testing::StrictMock; 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)using testing::WithArgs; 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing testing::_; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kData1[] = "FooAndBar"; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kData2[] = "EepAndBaz"; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kDataLen = 9; 40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const bool kIsServer = true; 41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const bool kShouldProcessData = true; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class TestStream : public ReliableQuicStream { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) TestStream(QuicStreamId id, 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicSession* session, 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool should_process_data) 48b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) : ReliableQuicStream(id, session), 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) should_process_data_(should_process_data) {} 50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual uint32 ProcessRawData(const char* data, uint32 data_len) OVERRIDE { 52558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_NE(0u, data_len); 53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DVLOG(1) << "ProcessData data_len: " << data_len; 54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) data_ += string(data, data_len); 55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return should_process_data_ ? data_len : 0; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 57b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual QuicPriority EffectivePriority() const OVERRIDE { 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return QuicUtils::HighestPriority(); 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) using ReliableQuicStream::WriteOrBufferData; 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) using ReliableQuicStream::CloseReadSide; 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) using ReliableQuicStream::CloseWriteSide; 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) using ReliableQuicStream::OnClose; 66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) private: 68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool should_process_data_; 69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) string data_; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> { 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ReliableQuicStreamTest() 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : initial_flow_control_window_bytes_(kMaxPacketSize), 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch zero_(QuicTime::Delta::Zero()), 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch supported_versions_(QuicSupportedVersions()) { 78b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) headers_[":host"] = "www.google.com"; 79b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) headers_[":path"] = "/index.hml"; 80b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) headers_[":scheme"] = "https"; 81558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch headers_["cookie"] = 82558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " 83558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "__utmc=160408618; " 84558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX" 85558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX" 86558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT" 87558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0" 88558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh" 89558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "1zFMi5vzcns38-8_Sns; " 90558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-" 91558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339" 92558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c" 93558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%" 94558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4" 95558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1" 96558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP" 97558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6" 98558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b" 99558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6" 100558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG" 101558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk" 102558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn" 103558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr" 104558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo "; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void set_supported_versions(const QuicVersionVector& versions) { 1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch supported_versions_ = versions; 1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 111b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) void Initialize(bool stream_should_process_data) { 1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch connection_ = 1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch new StrictMock<MockConnection>(kIsServer, supported_versions_); 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session_.reset(new StrictMock<MockSession>(connection_)); 115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // New streams rely on having the peer's flow control receive window 117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // negotiated in the config. 1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicConfigPeer::SetReceivedInitialFlowControlWindow( 1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch session_->config(), initial_flow_control_window_bytes_); 1206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow( 1216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) session_->config(), initial_flow_control_window_bytes_); 122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream_.reset(new TestStream(kHeadersStreamId, session_.get(), 124b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) stream_should_process_data)); 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) write_blocked_list_ = 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) QuicSessionPeer::GetWriteBlockedStreams(session_.get()); 127b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin_sent() { return ReliableQuicStreamPeer::FinSent(stream_.get()); } 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool rst_sent() { return ReliableQuicStreamPeer::RstSent(stream_.get()); } 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 132e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void set_initial_flow_control_window_bytes(uint32 val) { 133e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch initial_flow_control_window_bytes_ = val; 134e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool HasWriteBlockedStreams() { 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return write_blocked_list_->HasWriteBlockedCryptoOrHeadersStream() || 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) write_blocked_list_->HasWriteBlockedDataStreams(); 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) protected: 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockConnection* connection_; 143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<MockSession> session_; 144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<TestStream> stream_; 145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) SpdyHeaderBlock headers_; 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicWriteBlockedList* write_blocked_list_; 147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch uint32 initial_flow_control_window_bytes_; 1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicTime::Delta zero_; 1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicVersionVector supported_versions_; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteAllData) { 153b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Initialize(kShouldProcessData); 154b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size_t length = 1 + QuicPacketCreator::StreamFramePacketOverhead( 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, 15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PACKET_6BYTE_SEQUENCE_NUMBER, 0u, NOT_IN_FEC_GROUP); 15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) QuicConnectionPeer::GetPacketCreator(connection_)->set_max_packet_length( 15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) length); 16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)).WillOnce( 16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Return(QuicConsumedData(kDataLen, true))); 16323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(kData1, false, NULL); 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(HasWriteBlockedStreams()); 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, NoBlockingIfNoDataOrFin) { 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Initialize(kShouldProcessData); 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Write no data and no fin. If we consume nothing we should not be write 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // blocked. 17223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_DFATAL(stream_->WriteOrBufferData(StringPiece(), false, NULL), ""); 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(HasWriteBlockedStreams()); 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) { 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Initialize(kShouldProcessData); 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Write some data and no fin. If we consume some but not all of the data, 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // we should be write blocked a not all the data was consumed. 181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)) 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .WillOnce(Return(QuicConsumedData(1, false))); 18323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(StringPiece(kData1, 2), false, NULL); 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) { 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Initialize(kShouldProcessData); 189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Write some data and no fin. If we consume all the data but not the fin, 191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // we should be write blocked because the fin was not consumed. 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // (This should never actually happen as the fin should be sent out with the 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // last data) 194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)) 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .WillOnce(Return(QuicConsumedData(2, false))); 19623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(StringPiece(kData1, 2), true, NULL); 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) { 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Initialize(kShouldProcessData); 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Write no data and a fin. If we consume nothing we should be write blocked, 204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // as the fin was not consumed. 205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)) 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .WillOnce(Return(QuicConsumedData(0, false))); 20723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(StringPiece(), true, NULL); 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteOrBufferData) { 212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Initialize(kShouldProcessData); 213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(HasWriteBlockedStreams()); 21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size_t length = 1 + QuicPacketCreator::StreamFramePacketOverhead( 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, 21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PACKET_6BYTE_SEQUENCE_NUMBER, 0u, NOT_IN_FEC_GROUP); 21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) QuicConnectionPeer::GetPacketCreator(connection_)->set_max_packet_length( 21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) length); 22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).WillOnce( 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Return(QuicConsumedData(kDataLen - 1, false))); 22323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(kData1, false, NULL); 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(HasWriteBlockedStreams()); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Queue a bytes_consumed write. 22723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(kData2, false, NULL); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure we get the tail of the first write followed by the bytes_consumed 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InSequence s; 231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)). 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WillOnce(Return(QuicConsumedData(1, false))); 233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)). 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WillOnce(Return(QuicConsumedData(kDataLen - 2, false))); 235b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) stream_->OnCanWrite(); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // And finally the end of the bytes_consumed. 238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)). 239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) WillOnce(Return(QuicConsumedData(2, true))); 240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stream_->OnCanWrite(); 241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithFecProtectAlways) { 244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Initialize(kShouldProcessData); 245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Set FEC policy on stream. 247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ReliableQuicStreamPeer::SetFecPolicy(stream_.get(), FEC_PROTECT_ALWAYS); 248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_FALSE(HasWriteBlockedStreams()); 250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t length = 1 + QuicPacketCreator::StreamFramePacketOverhead( 2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, 252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) PACKET_6BYTE_SEQUENCE_NUMBER, 0u, IN_FEC_GROUP); 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) QuicConnectionPeer::GetPacketCreator(connection_)->set_max_packet_length( 254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) length); 255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Write first data onto stream, which will cause one session write. 257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _)).WillOnce( 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Return(QuicConsumedData(kDataLen - 1, false))); 259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stream_->WriteOrBufferData(kData1, false, NULL); 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(HasWriteBlockedStreams()); 261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Queue a bytes_consumed write. 263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stream_->WriteOrBufferData(kData2, false, NULL); 264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Make sure we get the tail of the first write followed by the bytes_consumed 266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) InSequence s; 267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _)). 268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) WillOnce(Return(QuicConsumedData(1, false))); 269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _)). 270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) WillOnce(Return(QuicConsumedData(kDataLen - 2, false))); 271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stream_->OnCanWrite(); 272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // And finally the end of the bytes_consumed. 274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _)). 275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) WillOnce(Return(QuicConsumedData(2, true))); 276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stream_->OnCanWrite(); 277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithFecProtectOptional) { 280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Initialize(kShouldProcessData); 281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Set FEC policy on stream. 283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ReliableQuicStreamPeer::SetFecPolicy(stream_.get(), FEC_PROTECT_OPTIONAL); 284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_FALSE(HasWriteBlockedStreams()); 286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t length = 1 + QuicPacketCreator::StreamFramePacketOverhead( 2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, 288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) PACKET_6BYTE_SEQUENCE_NUMBER, 0u, NOT_IN_FEC_GROUP); 289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) QuicConnectionPeer::GetPacketCreator(connection_)->set_max_packet_length( 290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) length); 291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Write first data onto stream, which will cause one session write. 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _)).WillOnce( 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Return(QuicConsumedData(kDataLen - 1, false))); 295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stream_->WriteOrBufferData(kData1, false, NULL); 296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(HasWriteBlockedStreams()); 297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Queue a bytes_consumed write. 299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stream_->WriteOrBufferData(kData2, false, NULL); 300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Make sure we get the tail of the first write followed by the bytes_consumed 302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) InSequence s; 303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _)). 304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) WillOnce(Return(QuicConsumedData(1, false))); 305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _)). 306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) WillOnce(Return(QuicConsumedData(kDataLen - 2, false))); 307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stream_->OnCanWrite(); 308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // And finally the end of the bytes_consumed. 310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _)). 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WillOnce(Return(QuicConsumedData(2, true))); 312b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) stream_->OnCanWrite(); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, ConnectionCloseAfterStreamClose) { 316b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Initialize(kShouldProcessData); 317b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 318b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) stream_->CloseReadSide(); 319b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) stream_->CloseWriteSide(); 320b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error()); 321b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error()); 3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR, false); 323b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error()); 324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error()); 325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, RstAlwaysSentIfNoFinSent) { 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For flow control accounting, a stream must send either a FIN or a RST frame 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // before termination. 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Test that if no FIN has been sent, we send a RST. 331b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Initialize(kShouldProcessData); 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(fin_sent()); 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(rst_sent()); 335b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Write some data, with no FIN. 337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)) 338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .WillOnce(Return(QuicConsumedData(1, false))); 33923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(StringPiece(kData1, 1), false, NULL); 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(fin_sent()); 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(rst_sent()); 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Now close the stream, and expect that we send a RST. 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*session_, SendRstStream(_, _, _)); 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_->OnClose(); 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(fin_sent()); 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(rst_sent()); 348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 349b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, RstNotSentIfFinSent) { 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For flow control accounting, a stream must send either a FIN or a RST frame 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // before termination. 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Test that if a FIN has been sent, we don't also send a RST. 354b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 355558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch Initialize(kShouldProcessData); 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(fin_sent()); 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(rst_sent()); 358558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Write some data, with FIN. 360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)) 361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .WillOnce(Return(QuicConsumedData(1, true))); 36223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(StringPiece(kData1, 1), true, NULL); 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(fin_sent()); 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(rst_sent()); 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Now close the stream, and expect that we do not send a RST. 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_->OnClose(); 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(fin_sent()); 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(rst_sent()); 370558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 371558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, OnlySendOneRst) { 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For flow control accounting, a stream must send either a FIN or a RST frame 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // before termination. 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Test that if a stream sends a RST, it doesn't send an additional RST during 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // OnClose() (this shouldn't be harmful, but we shouldn't do it anyway...) 377558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 378b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Initialize(kShouldProcessData); 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(fin_sent()); 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(rst_sent()); 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Reset the stream. 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int expected_resets = 1; 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*session_, SendRstStream(_, _, _)).Times(expected_resets); 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_->Reset(QUIC_STREAM_CANCELLED); 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(fin_sent()); 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(rst_sent()); 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Now close the stream (any further resets being sent would break the 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // expectation above). 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_->OnClose(); 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(fin_sent()); 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(rst_sent()); 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 396e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochTEST_F(ReliableQuicStreamTest, StreamFlowControlMultipleWindowUpdates) { 397e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch set_initial_flow_control_window_bytes(1000); 398e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 399e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Initialize(kShouldProcessData); 400e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 401e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // If we receive multiple WINDOW_UPDATES (potentially out of order), then we 402e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // want to make sure we latch the largest offset we see. 403e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 404e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Initially should be default. 405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ( 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) initial_flow_control_window_bytes_, 407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) QuicFlowControllerPeer::SendWindowOffset(stream_->flow_controller())); 408e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 409e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Check a single WINDOW_UPDATE results in correct offset. 410e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch QuicWindowUpdateFrame window_update_1(stream_->id(), 1234); 411e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch stream_->OnWindowUpdateFrame(window_update_1); 412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ( 413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) window_update_1.byte_offset, 414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) QuicFlowControllerPeer::SendWindowOffset(stream_->flow_controller())); 415e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 416e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Now send a few more WINDOW_UPDATES and make sure that only the largest is 417e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // remembered. 418e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch QuicWindowUpdateFrame window_update_2(stream_->id(), 1); 419e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch QuicWindowUpdateFrame window_update_3(stream_->id(), 9999); 420e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch QuicWindowUpdateFrame window_update_4(stream_->id(), 5678); 421e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch stream_->OnWindowUpdateFrame(window_update_2); 422e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch stream_->OnWindowUpdateFrame(window_update_3); 423e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch stream_->OnWindowUpdateFrame(window_update_4); 424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ( 425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) window_update_3.byte_offset, 426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) QuicFlowControllerPeer::SendWindowOffset(stream_->flow_controller())); 4270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 4280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4290529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(ReliableQuicStreamTest, StreamFlowControlShouldNotBlockInLessThanQ017) { 4300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(rjshade): Remove this test when we no longer have any versions < 4310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // QUIC_VERSION_17. 4320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Make sure we are using a version which does not support flow control. 4340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicVersion kTestQuicVersions[] = {QUIC_VERSION_16}; 4350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicVersionVector versions; 4360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (size_t i = 0; i < arraysize(kTestQuicVersions); ++i) { 4370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch versions.push_back(kTestQuicVersions[i]); 4380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 4390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch set_supported_versions(versions); 4400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Peer is not talking QUIC_VERSION_17 so assumes that it can send a zero 4420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // length flow control receive window with no consequences. 4430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch set_initial_flow_control_window_bytes(0); 4440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Initialize(kShouldProcessData); 4460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // The stream should _not_ be flow control blocked, because we are not talking 4480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // a version which has flow control enabled. 4490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_FALSE(stream_->flow_controller()->IsBlocked()); 450e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 451e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 45223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void SaveProxyAckNotifierDelegate( 45323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<QuicAckNotifier::DelegateInterface>* delegate_out, 45423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) QuicAckNotifier::DelegateInterface* delegate) { 45523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *delegate_out = delegate; 45623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 4570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 45823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithQuicAckNotifier) { 45923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) Initialize(kShouldProcessData); 46023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 46123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<MockAckNotifierDelegate> delegate( 46223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) new StrictMock<MockAckNotifierDelegate>); 46323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 46423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int kDataSize = 16 * 1024; 46523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const string kData(kDataSize, 'a'); 46623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 46723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int kFirstWriteSize = 100; 46823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int kSecondWriteSize = 50; 46923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int kLastWriteSize = kDataSize - kFirstWriteSize - kSecondWriteSize; 47023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 4710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Set a large flow control send window so this doesn't interfere with test. 4720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1); 4736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) session_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1); 4740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 47523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; 47623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 477f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)) 478f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor( 479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &SaveProxyAckNotifierDelegate, &proxy_delegate))), 480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Return(QuicConsumedData(kFirstWriteSize, false)))); 48123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(kData, false, delegate.get()); 482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(HasWriteBlockedStreams()); 48323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_CALL(*session_, 485f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) WritevData(kHeadersStreamId, _, _, _, _, proxy_delegate.get())) 486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .WillOnce(Return(QuicConsumedData(kSecondWriteSize, false))); 48723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->OnCanWrite(); 48823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 48923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // No ack expected for an empty write. 490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_CALL(*session_, 491f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) WritevData(kHeadersStreamId, _, _, _, _, proxy_delegate.get())) 492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .WillOnce(Return(QuicConsumedData(0, false))); 49323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->OnCanWrite(); 49423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_CALL(*session_, 496f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) WritevData(kHeadersStreamId, _, _, _, _, proxy_delegate.get())) 497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .WillOnce(Return(QuicConsumedData(kLastWriteSize, false))); 49823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->OnCanWrite(); 49923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 50023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // There were two writes, so OnAckNotification is not propagated 50123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // until the third Ack arrives. 5020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); 5030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch proxy_delegate->OnAckNotification(10, 20, 30, 40, zero_); 50423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 50523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // The arguments to delegate->OnAckNotification are the sum of the 50623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // arguments to proxy_delegate OnAckNotification calls. 5071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_CALL(*delegate.get(), OnAckNotification(111, 222, 333, 444, zero_)); 5080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch proxy_delegate->OnAckNotification(100, 200, 300, 400, zero_); 50923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 51023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 51123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Verify delegate behavior when packets are acked before the 51223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WritevData call that sends out the last byte. 51323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteOrBufferDataAckNotificationBeforeFlush) { 51423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) Initialize(kShouldProcessData); 51523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 51623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<MockAckNotifierDelegate> delegate( 51723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) new StrictMock<MockAckNotifierDelegate>); 51823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 51923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int kDataSize = 16 * 1024; 52023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const string kData(kDataSize, 'a'); 52123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 52223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int kInitialWriteSize = 100; 52323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 5240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Set a large flow control send window so this doesn't interfere with test. 5250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1); 5266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) session_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1); 5270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 52823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; 52923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 530f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)) 531f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor( 532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &SaveProxyAckNotifierDelegate, &proxy_delegate))), 533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Return(QuicConsumedData(kInitialWriteSize, false)))); 53423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(kData, false, delegate.get()); 535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(HasWriteBlockedStreams()); 53623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 53723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Handle the ack of the first write. 5380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); 53923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) proxy_delegate = NULL; 54023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 541f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)).WillOnce( 542f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DoAll(WithArgs<5>(Invoke(CreateFunctor( 543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &SaveProxyAckNotifierDelegate, &proxy_delegate))), 544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Return(QuicConsumedData(kDataSize - kInitialWriteSize, false)))); 54523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->OnCanWrite(); 54623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 54723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Handle the ack for the second write. 5481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_CALL(*delegate.get(), OnAckNotification(101, 202, 303, 404, zero_)); 5490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch proxy_delegate->OnAckNotification(100, 200, 300, 400, zero_); 55023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 55123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 55223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Verify delegate behavior when WriteOrBufferData does not buffer. 55323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferNoBuffer) { 55423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) Initialize(kShouldProcessData); 55523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 55623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<MockAckNotifierDelegate> delegate( 55723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) new StrictMock<MockAckNotifierDelegate>); 55823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 55923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; 56023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 561f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)) 562f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor( 563cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &SaveProxyAckNotifierDelegate, &proxy_delegate))), 564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Return(QuicConsumedData(kDataLen, true)))); 56523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(kData1, true, delegate.get()); 566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(HasWriteBlockedStreams()); 56723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 56823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Handle the ack. 5691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_CALL(*delegate.get(), OnAckNotification(1, 2, 3, 4, zero_)); 5700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); 57123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 57223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 57323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Verify delegate behavior when WriteOrBufferData buffers all the data. 57423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, BufferOnWriteAndBufferDataWithAckNotifer) { 57523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) Initialize(kShouldProcessData); 57623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 57723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<MockAckNotifierDelegate> delegate( 57823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) new StrictMock<MockAckNotifierDelegate>); 57923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 58023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; 58123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 582f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)) 583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .WillOnce(Return(QuicConsumedData(0, false))); 58423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(kData1, true, delegate.get()); 585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(HasWriteBlockedStreams()); 58623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 587f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)) 588f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor( 589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &SaveProxyAckNotifierDelegate, &proxy_delegate))), 590cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Return(QuicConsumedData(kDataLen, true)))); 59123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->OnCanWrite(); 59223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 59323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Handle the ack. 5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_CALL(*delegate.get(), OnAckNotification(1, 2, 3, 4, zero_)); 5950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); 59623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 59723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 59823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Verify delegate behavior when WriteOrBufferData when the FIN is 59923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// sent out in a different packet. 60023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferOnlyFinRemains) { 60123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) Initialize(kShouldProcessData); 60223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 60323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<MockAckNotifierDelegate> delegate( 60423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) new StrictMock<MockAckNotifierDelegate>); 60523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 60623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; 60723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 608f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)) 609f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor( 610cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &SaveProxyAckNotifierDelegate, &proxy_delegate))), 611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Return(QuicConsumedData(kDataLen, false)))); 61223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->WriteOrBufferData(kData1, true, delegate.get()); 613cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(HasWriteBlockedStreams()); 61423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 615f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)) 616f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor( 617cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &SaveProxyAckNotifierDelegate, &proxy_delegate))), 618cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Return(QuicConsumedData(0, true)))); 61923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stream_->OnCanWrite(); 62023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 62123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Handle the acks. 6220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); 6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_CALL(*delegate.get(), OnAckNotification(11, 22, 33, 44, zero_)); 6240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch proxy_delegate->OnAckNotification(10, 20, 30, 40, zero_); 62523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 62623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 62746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Verify that when we receive a packet which violates flow control (i.e. sends 62846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// too much data on the stream) that the stream sequencer never sees this frame, 62946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// as we check for violation and close the connection early. 63046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, 63146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) StreamSequencerNeverSeesPacketsViolatingFlowControl) { 63246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Initialize(kShouldProcessData); 63346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 63446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Receive a stream frame that violates flow control: the byte offset is 63546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // higher than the receive window offset. 63646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) QuicStreamFrame frame(stream_->id(), false, 6376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) kInitialSessionFlowControlWindowForTest + 1, 63846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MakeIOVector(".")); 63946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_GT(frame.offset, QuicFlowControllerPeer::ReceiveWindowOffset( 64046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) stream_->flow_controller())); 64146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 64246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Stream should not accept the frame, and the connection should be closed. 64346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_CALL(*connection_, 64446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); 6455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stream_->OnStreamFrame(frame); 64646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 64746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 648f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, FinalByteOffsetFromFin) { 649f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Initialize(kShouldProcessData); 650f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 651f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_FALSE(stream_->HasFinalReceivedByteOffset()); 652f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 653f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) QuicStreamFrame stream_frame_no_fin(stream_->id(), false, 1234, 654f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MakeIOVector(".")); 655f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stream_->OnStreamFrame(stream_frame_no_fin); 656f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_FALSE(stream_->HasFinalReceivedByteOffset()); 657f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 658f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, 659f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MakeIOVector(".")); 660f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stream_->OnStreamFrame(stream_frame_with_fin); 661f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(stream_->HasFinalReceivedByteOffset()); 662f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 663f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 664f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, FinalByteOffsetFromRst) { 665f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Initialize(kShouldProcessData); 666f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 667f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_FALSE(stream_->HasFinalReceivedByteOffset()); 668f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) QuicRstStreamFrame rst_frame(stream_->id(), QUIC_STREAM_CANCELLED, 1234); 669f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stream_->OnStreamReset(rst_frame); 670f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(stream_->HasFinalReceivedByteOffset()); 671f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 672f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace test 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace net 676