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