reliable_quic_stream_test.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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"
9e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "net/quic/quic_flags.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_utils.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_write_blocked_list.h"
12b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/quic/spdy_utils.h"
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "net/quic/test_tools/quic_config_peer.h"
1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/quic/test_tools/quic_connection_peer.h"
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "net/quic/test_tools/quic_flow_controller_peer.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/quic/test_tools/quic_session_peer.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/test_tools/reliable_quic_stream_peer.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/test/gtest_util.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "testing/gmock_mutant.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::StringPiece;
24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using std::min;
2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)using testing::CreateFunctor;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::InSequence;
2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)using testing::Invoke;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Return;
29b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using testing::SaveArg;
30b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using testing::StrictMock;
3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)using testing::WithArgs;
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing testing::_;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kData1[] = "FooAndBar";
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kData2[] = "EepAndBaz";
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kDataLen = 9;
41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const bool kIsServer = true;
42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const bool kShouldProcessData = true;
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class TestStream : public ReliableQuicStream {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  TestStream(QuicStreamId id,
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             QuicSession* session,
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             bool should_process_data)
49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      : ReliableQuicStream(id, session),
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        should_process_data_(should_process_data) {}
51b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual uint32 ProcessRawData(const char* data, uint32 data_len) OVERRIDE {
53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    EXPECT_NE(0u, data_len);
54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DVLOG(1) << "ProcessData data_len: " << data_len;
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    data_ += string(data, data_len);
56b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return should_process_data_ ? data_len : 0;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual QuicPriority EffectivePriority() const OVERRIDE {
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return QuicUtils::HighestPriority();
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  using ReliableQuicStream::WriteOrBufferData;
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  using ReliableQuicStream::CloseReadSide;
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  using ReliableQuicStream::CloseWriteSide;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  using ReliableQuicStream::OnClose;
67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) private:
69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool should_process_data_;
70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  string data_;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  ReliableQuicStreamTest()
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      : initial_flow_control_window_bytes_(kMaxPacketSize),
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        zero_(QuicTime::Delta::Zero()),
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        supported_versions_(QuicSupportedVersions()) {
79b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    headers_[":host"] = "www.google.com";
80b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    headers_[":path"] = "/index.hml";
81b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    headers_[":scheme"] = "https";
82558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    headers_["cookie"] =
83558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
84558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "__utmc=160408618; "
85558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
86558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
87558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
88558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
89558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
90558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "1zFMi5vzcns38-8_Sns; "
91558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
92558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
93558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
94558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
95558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
96558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
97558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
98558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
99558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
100558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
101558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
102558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
103558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
104558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
105558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void set_supported_versions(const QuicVersionVector& versions) {
1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    supported_versions_ = versions;
1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
112b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void Initialize(bool stream_should_process_data) {
1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    connection_ =
1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        new StrictMock<MockConnection>(kIsServer, supported_versions_);
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    session_.reset(new StrictMock<MockSession>(connection_));
116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // New streams rely on having the peer's flow control receive window
118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // negotiated in the config.
1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    QuicConfigPeer::SetReceivedInitialFlowControlWindow(
1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        session_->config(), initial_flow_control_window_bytes_);
1216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(
1226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        session_->config(), initial_flow_control_window_bytes_);
123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    stream_.reset(new TestStream(kHeadersStreamId, session_.get(),
125b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                 stream_should_process_data));
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    write_blocked_list_ =
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        QuicSessionPeer::GetWriteBlockedStreams(session_.get());
128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool fin_sent() { return ReliableQuicStreamPeer::FinSent(stream_.get()); }
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool rst_sent() { return ReliableQuicStreamPeer::RstSent(stream_.get()); }
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
133e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  void set_initial_flow_control_window_bytes(uint32 val) {
134e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    initial_flow_control_window_bytes_ = val;
135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool HasWriteBlockedStreams() {
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return write_blocked_list_->HasWriteBlockedCryptoOrHeadersStream() ||
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)           write_blocked_list_->HasWriteBlockedDataStreams();
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) protected:
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockConnection* connection_;
144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_ptr<MockSession> session_;
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_ptr<TestStream> stream_;
146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  SpdyHeaderBlock headers_;
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicWriteBlockedList* write_blocked_list_;
148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  uint32 initial_flow_control_window_bytes_;
1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicTime::Delta zero_;
1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicVersionVector supported_versions_;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteAllData) {
154b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  Initialize(kShouldProcessData);
155b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  size_t length = 1 + QuicPacketCreator::StreamFramePacketOverhead(
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      PACKET_6BYTE_SEQUENCE_NUMBER, 0u, NOT_IN_FEC_GROUP);
15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  QuicConnectionPeer::GetPacketCreator(connection_)->set_max_packet_length(
16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      length);
16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)).WillOnce(
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      Return(QuicConsumedData(kDataLen, true)));
16423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(kData1, false, NULL);
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(HasWriteBlockedStreams());
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, NoBlockingIfNoDataOrFin) {
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Initialize(kShouldProcessData);
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Write no data and no fin.  If we consume nothing we should not be write
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // blocked.
17323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_DFATAL(stream_->WriteOrBufferData(StringPiece(), false, NULL), "");
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(HasWriteBlockedStreams());
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) {
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Initialize(kShouldProcessData);
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Write some data and no fin.  If we consume some but not all of the data,
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // we should be write blocked a not all the data was consumed.
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _))
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      .WillOnce(Return(QuicConsumedData(1, false)));
18423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(StringPiece(kData1, 2), false, NULL);
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) {
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Initialize(kShouldProcessData);
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Write some data and no fin.  If we consume all the data but not the fin,
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // we should be write blocked because the fin was not consumed.
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // (This should never actually happen as the fin should be sent out with the
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // last data)
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _))
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      .WillOnce(Return(QuicConsumedData(2, false)));
19723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(StringPiece(kData1, 2), true, NULL);
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) {
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Initialize(kShouldProcessData);
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Write no data and a fin.  If we consume nothing we should be write blocked,
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // as the fin was not consumed.
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _))
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      .WillOnce(Return(QuicConsumedData(0, false)));
20823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(StringPiece(), true, NULL);
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteOrBufferData) {
213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  Initialize(kShouldProcessData);
214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(HasWriteBlockedStreams());
21646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  size_t length = 1 + QuicPacketCreator::StreamFramePacketOverhead(
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      PACKET_6BYTE_SEQUENCE_NUMBER, 0u, NOT_IN_FEC_GROUP);
21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  QuicConnectionPeer::GetPacketCreator(connection_)->set_max_packet_length(
22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      length);
22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).WillOnce(
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(QuicConsumedData(kDataLen - 1, false)));
22423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(kData1, false, NULL);
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(HasWriteBlockedStreams());
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Queue a bytes_consumed write.
22823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(kData2, false, NULL);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure we get the tail of the first write followed by the bytes_consumed
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InSequence s;
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WillOnce(Return(QuicConsumedData(1, false)));
234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
236b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  stream_->OnCanWrite();
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // And finally the end of the bytes_consumed.
239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      WillOnce(Return(QuicConsumedData(2, true)));
241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  stream_->OnCanWrite();
242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithFecProtectAlways) {
245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Initialize(kShouldProcessData);
246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Set FEC policy on stream.
248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ReliableQuicStreamPeer::SetFecPolicy(stream_.get(), FEC_PROTECT_ALWAYS);
249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(HasWriteBlockedStreams());
251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  size_t length = 1 + QuicPacketCreator::StreamFramePacketOverhead(
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      PACKET_6BYTE_SEQUENCE_NUMBER, 0u, IN_FEC_GROUP);
254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConnectionPeer::GetPacketCreator(connection_)->set_max_packet_length(
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      length);
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Write first data onto stream, which will cause one session write.
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _)).WillOnce(
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      Return(QuicConsumedData(kDataLen - 1, false)));
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  stream_->WriteOrBufferData(kData1, false, NULL);
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(HasWriteBlockedStreams());
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Queue a bytes_consumed write.
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  stream_->WriteOrBufferData(kData2, false, NULL);
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Make sure we get the tail of the first write followed by the bytes_consumed
267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  InSequence s;
268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _)).
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      WillOnce(Return(QuicConsumedData(1, false)));
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _)).
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  stream_->OnCanWrite();
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // And finally the end of the bytes_consumed.
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(_, _, _, _, MUST_FEC_PROTECT, _)).
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      WillOnce(Return(QuicConsumedData(2, true)));
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  stream_->OnCanWrite();
278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithFecProtectOptional) {
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Initialize(kShouldProcessData);
282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Set FEC policy on stream.
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ReliableQuicStreamPeer::SetFecPolicy(stream_.get(), FEC_PROTECT_OPTIONAL);
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(HasWriteBlockedStreams());
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  size_t length = 1 + QuicPacketCreator::StreamFramePacketOverhead(
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      PACKET_6BYTE_SEQUENCE_NUMBER, 0u, NOT_IN_FEC_GROUP);
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConnectionPeer::GetPacketCreator(connection_)->set_max_packet_length(
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      length);
292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Write first data onto stream, which will cause one session write.
294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _)).WillOnce(
295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      Return(QuicConsumedData(kDataLen - 1, false)));
296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  stream_->WriteOrBufferData(kData1, false, NULL);
297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(HasWriteBlockedStreams());
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Queue a bytes_consumed write.
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  stream_->WriteOrBufferData(kData2, false, NULL);
301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Make sure we get the tail of the first write followed by the bytes_consumed
303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  InSequence s;
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _)).
305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      WillOnce(Return(QuicConsumedData(1, false)));
306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _)).
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  stream_->OnCanWrite();
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // And finally the end of the bytes_consumed.
311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(_, _, _, _, MAY_FEC_PROTECT, _)).
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WillOnce(Return(QuicConsumedData(2, true)));
313b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  stream_->OnCanWrite();
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, ConnectionCloseAfterStreamClose) {
317b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  Initialize(kShouldProcessData);
318b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
319b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  stream_->CloseReadSide();
320b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  stream_->CloseWriteSide();
321b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
322b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error());
3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR, false);
324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error());
326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
327b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, RstAlwaysSentIfNoFinSent) {
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // For flow control accounting, a stream must send either a FIN or a RST frame
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // before termination.
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Test that if no FIN has been sent, we send a RST.
332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
333b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  Initialize(kShouldProcessData);
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(fin_sent());
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(rst_sent());
336b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Write some data, with no FIN.
338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _))
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      .WillOnce(Return(QuicConsumedData(1, false)));
34023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(StringPiece(kData1, 1), false, NULL);
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(fin_sent());
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(rst_sent());
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Now close the stream, and expect that we send a RST.
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(*session_, SendRstStream(_, _, _));
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stream_->OnClose();
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(fin_sent());
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(rst_sent());
349b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
350b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, RstNotSentIfFinSent) {
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // For flow control accounting, a stream must send either a FIN or a RST frame
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // before termination.
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Test that if a FIN has been sent, we don't also send a RST.
355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
356558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Initialize(kShouldProcessData);
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(fin_sent());
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(rst_sent());
359558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Write some data, with FIN.
361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _))
362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      .WillOnce(Return(QuicConsumedData(1, true)));
36323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(StringPiece(kData1, 1), true, NULL);
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(fin_sent());
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(rst_sent());
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Now close the stream, and expect that we do not send a RST.
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stream_->OnClose();
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(fin_sent());
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(rst_sent());
371558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
372558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, OnlySendOneRst) {
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // For flow control accounting, a stream must send either a FIN or a RST frame
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // before termination.
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Test that if a stream sends a RST, it doesn't send an additional RST during
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // OnClose() (this shouldn't be harmful, but we shouldn't do it anyway...)
378558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
379b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  Initialize(kShouldProcessData);
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(fin_sent());
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(rst_sent());
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Reset the stream.
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int expected_resets = 1;
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(*session_, SendRstStream(_, _, _)).Times(expected_resets);
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stream_->Reset(QUIC_STREAM_CANCELLED);
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(fin_sent());
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(rst_sent());
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Now close the stream (any further resets being sent would break the
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // expectation above).
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stream_->OnClose();
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(fin_sent());
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(rst_sent());
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
397e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochTEST_F(ReliableQuicStreamTest, StreamFlowControlMultipleWindowUpdates) {
398e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  set_initial_flow_control_window_bytes(1000);
399e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
400e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  Initialize(kShouldProcessData);
401e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
402e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // If we receive multiple WINDOW_UPDATES (potentially out of order), then we
403e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // want to make sure we latch the largest offset we see.
404e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
405e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Initially should be default.
406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(
407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      initial_flow_control_window_bytes_,
408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      QuicFlowControllerPeer::SendWindowOffset(stream_->flow_controller()));
409e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
410e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Check a single WINDOW_UPDATE results in correct offset.
411e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  QuicWindowUpdateFrame window_update_1(stream_->id(), 1234);
412e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  stream_->OnWindowUpdateFrame(window_update_1);
413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(
414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      window_update_1.byte_offset,
415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      QuicFlowControllerPeer::SendWindowOffset(stream_->flow_controller()));
416e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
417e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Now send a few more WINDOW_UPDATES and make sure that only the largest is
418e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // remembered.
419e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  QuicWindowUpdateFrame window_update_2(stream_->id(), 1);
420e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  QuicWindowUpdateFrame window_update_3(stream_->id(), 9999);
421e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  QuicWindowUpdateFrame window_update_4(stream_->id(), 5678);
422e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  stream_->OnWindowUpdateFrame(window_update_2);
423e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  stream_->OnWindowUpdateFrame(window_update_3);
424e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  stream_->OnWindowUpdateFrame(window_update_4);
425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(
426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      window_update_3.byte_offset,
427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      QuicFlowControllerPeer::SendWindowOffset(stream_->flow_controller()));
4280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4300529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(ReliableQuicStreamTest, StreamFlowControlShouldNotBlockInLessThanQ017) {
4310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // TODO(rjshade): Remove this test when we no longer have any versions <
4320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  //                QUIC_VERSION_17.
4330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Make sure we are using a version which does not support flow control.
4350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicVersion kTestQuicVersions[] = {QUIC_VERSION_16};
4360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicVersionVector versions;
4370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (size_t i = 0; i < arraysize(kTestQuicVersions); ++i) {
4380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    versions.push_back(kTestQuicVersions[i]);
4390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  set_supported_versions(versions);
4410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Peer is not talking QUIC_VERSION_17 so assumes that it can send a zero
4430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // length flow control receive window with no consequences.
4440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  set_initial_flow_control_window_bytes(0);
4450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Initialize(kShouldProcessData);
4470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // The stream should _not_ be flow control blocked, because we are not talking
4490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // a version which has flow control enabled.
4500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_FALSE(stream_->flow_controller()->IsBlocked());
451e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
452e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
45323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void SaveProxyAckNotifierDelegate(
45423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    scoped_refptr<QuicAckNotifier::DelegateInterface>* delegate_out,
45523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    QuicAckNotifier::DelegateInterface* delegate) {
45623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  *delegate_out = delegate;
45723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
4580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
45923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithQuicAckNotifier) {
46023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  Initialize(kShouldProcessData);
46123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
46223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<MockAckNotifierDelegate> delegate(
46323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new StrictMock<MockAckNotifierDelegate>);
46423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
46523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const int kDataSize = 16 * 1024;
46623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const string kData(kDataSize, 'a');
46723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
46823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const int kFirstWriteSize = 100;
46923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const int kSecondWriteSize = 50;
47023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const int kLastWriteSize = kDataSize - kFirstWriteSize - kSecondWriteSize;
47123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Set a large flow control send window so this doesn't interfere with test.
4730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
474f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (FLAGS_enable_quic_connection_flow_control_2) {
475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    session_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
476010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
4770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
47823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
47923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
480f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _))
481f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor(
482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          &SaveProxyAckNotifierDelegate, &proxy_delegate))),
483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      Return(QuicConsumedData(kFirstWriteSize, false))));
48423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(kData, false, delegate.get());
485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(HasWriteBlockedStreams());
48623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_CALL(*session_,
488f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              WritevData(kHeadersStreamId, _, _, _, _, proxy_delegate.get()))
489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      .WillOnce(Return(QuicConsumedData(kSecondWriteSize, false)));
49023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->OnCanWrite();
49123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
49223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // No ack expected for an empty write.
493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_CALL(*session_,
494f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              WritevData(kHeadersStreamId, _, _, _, _, proxy_delegate.get()))
495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      .WillOnce(Return(QuicConsumedData(0, false)));
49623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->OnCanWrite();
49723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_CALL(*session_,
499f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              WritevData(kHeadersStreamId, _, _, _, _, proxy_delegate.get()))
500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      .WillOnce(Return(QuicConsumedData(kLastWriteSize, false)));
50123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->OnCanWrite();
50223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
50323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // There were two writes, so OnAckNotification is not propagated
50423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // until the third Ack arrives.
5050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_);
5060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  proxy_delegate->OnAckNotification(10, 20, 30, 40, zero_);
50723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
50823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // The arguments to delegate->OnAckNotification are the sum of the
50923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // arguments to proxy_delegate OnAckNotification calls.
5100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_CALL(*delegate, OnAckNotification(111, 222, 333, 444, zero_));
5110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  proxy_delegate->OnAckNotification(100, 200, 300, 400, zero_);
51223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
51323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
51423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Verify delegate behavior when packets are acked before the
51523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WritevData call that sends out the last byte.
51623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteOrBufferDataAckNotificationBeforeFlush) {
51723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  Initialize(kShouldProcessData);
51823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
51923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<MockAckNotifierDelegate> delegate(
52023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new StrictMock<MockAckNotifierDelegate>);
52123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
52223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const int kDataSize = 16 * 1024;
52323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const string kData(kDataSize, 'a');
52423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
52523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const int kInitialWriteSize = 100;
52623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
5270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Set a large flow control send window so this doesn't interfere with test.
5280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
529f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (FLAGS_enable_quic_connection_flow_control_2) {
530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    session_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
531010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
5320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
53323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
53423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
535f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _))
536f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor(
537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          &SaveProxyAckNotifierDelegate, &proxy_delegate))),
538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      Return(QuicConsumedData(kInitialWriteSize, false))));
53923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(kData, false, delegate.get());
540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(HasWriteBlockedStreams());
54123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
54223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Handle the ack of the first write.
5430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_);
54423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  proxy_delegate = NULL;
54523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
546f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _)).WillOnce(
547f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      DoAll(WithArgs<5>(Invoke(CreateFunctor(
548cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                &SaveProxyAckNotifierDelegate, &proxy_delegate))),
549cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            Return(QuicConsumedData(kDataSize - kInitialWriteSize, false))));
55023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->OnCanWrite();
55123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
55223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Handle the ack for the second write.
5530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_CALL(*delegate, OnAckNotification(101, 202, 303, 404, zero_));
5540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  proxy_delegate->OnAckNotification(100, 200, 300, 400, zero_);
55523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
55623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
55723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Verify delegate behavior when WriteOrBufferData does not buffer.
55823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferNoBuffer) {
55923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  Initialize(kShouldProcessData);
56023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
56123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<MockAckNotifierDelegate> delegate(
56223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new StrictMock<MockAckNotifierDelegate>);
56323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
56423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
56523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
566f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _))
567f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor(
568cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          &SaveProxyAckNotifierDelegate, &proxy_delegate))),
569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      Return(QuicConsumedData(kDataLen, true))));
57023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(kData1, true, delegate.get());
571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(HasWriteBlockedStreams());
57223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
57323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Handle the ack.
5740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_CALL(*delegate, OnAckNotification(1, 2, 3, 4, zero_));
5750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_);
57623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
57723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
57823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Verify delegate behavior when WriteOrBufferData buffers all the data.
57923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, BufferOnWriteAndBufferDataWithAckNotifer) {
58023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  Initialize(kShouldProcessData);
58123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
58223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<MockAckNotifierDelegate> delegate(
58323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new StrictMock<MockAckNotifierDelegate>);
58423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
58523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
58623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
587f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _))
588cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      .WillOnce(Return(QuicConsumedData(0, false)));
58923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(kData1, true, delegate.get());
590cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(HasWriteBlockedStreams());
59123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
592f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _))
593f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor(
594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          &SaveProxyAckNotifierDelegate, &proxy_delegate))),
595cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      Return(QuicConsumedData(kDataLen, true))));
59623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->OnCanWrite();
59723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
59823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Handle the ack.
5990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_CALL(*delegate, OnAckNotification(1, 2, 3, 4, zero_));
6000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_);
60123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
60223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
60323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Verify delegate behavior when WriteOrBufferData when the FIN is
60423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// sent out in a different packet.
60523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferOnlyFinRemains) {
60623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  Initialize(kShouldProcessData);
60723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
60823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<MockAckNotifierDelegate> delegate(
60923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new StrictMock<MockAckNotifierDelegate>);
61023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
61123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
61223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
613f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _))
614f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor(
615cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          &SaveProxyAckNotifierDelegate, &proxy_delegate))),
616cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      Return(QuicConsumedData(kDataLen, false))));
61723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->WriteOrBufferData(kData1, true, delegate.get());
618cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(HasWriteBlockedStreams());
61923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
620f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*session_, WritevData(kHeadersStreamId, _, _, _, _, _))
621f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      .WillOnce(DoAll(WithArgs<5>(Invoke(CreateFunctor(
622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          &SaveProxyAckNotifierDelegate, &proxy_delegate))),
623cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      Return(QuicConsumedData(0, true))));
62423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stream_->OnCanWrite();
62523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
62623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Handle the acks.
6270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_);
6280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_CALL(*delegate, OnAckNotification(11, 22, 33, 44, zero_));
6290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  proxy_delegate->OnAckNotification(10, 20, 30, 40, zero_);
63023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
63123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
63246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Verify that when we receive a packet which violates flow control (i.e. sends
63346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// too much data on the stream) that the stream sequencer never sees this frame,
63446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// as we check for violation and close the connection early.
63546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ReliableQuicStreamTest,
63646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)       StreamSequencerNeverSeesPacketsViolatingFlowControl) {
63746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ValueRestore<bool> old_connection_flag(
638f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      &FLAGS_enable_quic_connection_flow_control_2, true);
63946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
64046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  Initialize(kShouldProcessData);
64146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
64246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Receive a stream frame that violates flow control: the byte offset is
64346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // higher than the receive window offset.
64446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  QuicStreamFrame frame(stream_->id(), false,
6456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        kInitialSessionFlowControlWindowForTest + 1,
64646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        MakeIOVector("."));
64746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_GT(frame.offset, QuicFlowControllerPeer::ReceiveWindowOffset(
64846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                              stream_->flow_controller()));
64946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
65046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Stream should not accept the frame, and the connection should be closed.
65146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_CALL(*connection_,
65246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)              SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA));
6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  stream_->OnStreamFrame(frame);
65446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
65546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
656f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, FinalByteOffsetFromFin) {
657f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Initialize(kShouldProcessData);
658f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
659f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(stream_->HasFinalReceivedByteOffset());
660f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
661f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicStreamFrame stream_frame_no_fin(stream_->id(), false, 1234,
662f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                      MakeIOVector("."));
663f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  stream_->OnStreamFrame(stream_frame_no_fin);
664f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(stream_->HasFinalReceivedByteOffset());
665f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
666f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234,
667f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                        MakeIOVector("."));
668f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  stream_->OnStreamFrame(stream_frame_with_fin);
669f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(stream_->HasFinalReceivedByteOffset());
670f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
671f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
672f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ReliableQuicStreamTest, FinalByteOffsetFromRst) {
673f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Initialize(kShouldProcessData);
674f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
675f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(stream_->HasFinalReceivedByteOffset());
676f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicRstStreamFrame rst_frame(stream_->id(), QUIC_STREAM_CANCELLED, 1234);
677f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  stream_->OnStreamReset(rst_frame);
678f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(stream_->HasFinalReceivedByteOffset());
679f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
680f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace test
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
684