// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/quic/quic_data_stream.h"

#include "net/quic/quic_ack_notifier.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_utils.h"
#include "net/quic/quic_write_blocked_list.h"
#include "net/quic/spdy_utils.h"
#include "net/quic/test_tools/quic_flow_controller_peer.h"
#include "net/quic/test_tools/quic_session_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/quic/test_tools/reliable_quic_stream_peer.h"
#include "net/test/gtest_util.h"
#include "testing/gmock/include/gmock/gmock.h"

using base::StringPiece;
using std::min;
using std::string;
using testing::Return;
using testing::StrictMock;
using testing::_;

namespace net {
namespace test {
namespace {

const bool kShouldProcessData = true;

class TestStream : public QuicDataStream {
 public:
  TestStream(QuicStreamId id,
             QuicSpdySession* session,
             bool should_process_data)
      : QuicDataStream(id, session),
        should_process_data_(should_process_data) {}

  uint32 ProcessData(const char* data, uint32 data_len) override {
    EXPECT_NE(0u, data_len);
    DVLOG(1) << "ProcessData data_len: " << data_len;
    data_ += string(data, data_len);
    return should_process_data_ ? data_len : 0;
  }

  using ReliableQuicStream::WriteOrBufferData;
  using ReliableQuicStream::CloseReadSide;
  using ReliableQuicStream::CloseWriteSide;

  const string& data() const { return data_; }

 private:
  bool should_process_data_;
  string data_;
};

class QuicDataStreamTest : public ::testing::TestWithParam<QuicVersion> {
 public:
  QuicDataStreamTest() {
    headers_[":host"] = "www.google.com";
    headers_[":path"] = "/index.hml";
    headers_[":scheme"] = "https";
    headers_["cookie"] =
        "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
        "__utmc=160408618; "
        "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
        "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
        "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
        "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
        "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
        "1zFMi5vzcns38-8_Sns; "
        "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
        "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
        "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
        "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
        "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
        "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
        "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
        "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
        "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
        "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
        "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
        "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
        "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
        "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
        "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
  }

  void Initialize(bool stream_should_process_data) {
    connection_ = new testing::StrictMock<MockConnection>(
        Perspective::IS_SERVER, SupportedVersions(GetParam()));
    session_.reset(new testing::StrictMock<MockQuicSpdySession>(connection_));
    stream_.reset(new TestStream(kClientDataStreamId1, session_.get(),
                                 stream_should_process_data));
    stream2_.reset(new TestStream(kClientDataStreamId2, session_.get(),
                                  stream_should_process_data));
    write_blocked_list_ =
        QuicSessionPeer::GetWriteBlockedStreams(session_.get());
  }

 protected:
  MockConnection* connection_;
  scoped_ptr<MockQuicSpdySession> session_;
  scoped_ptr<TestStream> stream_;
  scoped_ptr<TestStream> stream2_;
  SpdyHeaderBlock headers_;
  QuicWriteBlockedList* write_blocked_list_;
};

INSTANTIATE_TEST_CASE_P(Tests, QuicDataStreamTest,
                        ::testing::ValuesIn(QuicSupportedVersions()));

TEST_P(QuicDataStreamTest, ProcessHeaders) {
  Initialize(kShouldProcessData);

  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority());
  stream_->OnStreamHeaders(headers);
  EXPECT_EQ("", stream_->data());
  EXPECT_EQ(headers, stream_->decompressed_headers());
  stream_->OnStreamHeadersComplete(false, headers.size());
  EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority());
  EXPECT_EQ("", stream_->data());
  EXPECT_EQ(headers, stream_->decompressed_headers());
  EXPECT_FALSE(stream_->IsDoneReading());
}

TEST_P(QuicDataStreamTest, MarkHeadersConsumed) {
  Initialize(kShouldProcessData);

  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  string body = "this is the body";

  stream_->OnStreamHeaders(headers);
  stream_->OnStreamHeadersComplete(false, headers.size());
  EXPECT_EQ(headers, stream_->decompressed_headers());

  headers.erase(0, 10);
  stream_->MarkHeadersConsumed(10);
  EXPECT_EQ(headers, stream_->decompressed_headers());

  stream_->MarkHeadersConsumed(headers.length());
  EXPECT_EQ("", stream_->decompressed_headers());
}

TEST_P(QuicDataStreamTest, ProcessHeadersAndBody) {
  Initialize(kShouldProcessData);

  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  string body = "this is the body";

  stream_->OnStreamHeaders(headers);
  EXPECT_EQ("", stream_->data());
  EXPECT_EQ(headers, stream_->decompressed_headers());
  stream_->OnStreamHeadersComplete(false, headers.size());
  EXPECT_EQ(headers, stream_->decompressed_headers());
  stream_->MarkHeadersConsumed(headers.length());
  QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body));
  stream_->OnStreamFrame(frame);
  EXPECT_EQ("", stream_->decompressed_headers());
  EXPECT_EQ(body, stream_->data());
}

TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragments) {
  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  string body = "this is the body";

  for (size_t fragment_size = 1; fragment_size < body.size();
       ++fragment_size) {
    Initialize(kShouldProcessData);
    for (size_t offset = 0; offset < headers.size();
         offset += fragment_size) {
      size_t remaining_data = headers.size() - offset;
      StringPiece fragment(headers.data() + offset,
                           min(fragment_size, remaining_data));
      stream_->OnStreamHeaders(fragment);
    }
    stream_->OnStreamHeadersComplete(false, headers.size());
    ASSERT_EQ(headers, stream_->decompressed_headers())
        << "fragment_size: " << fragment_size;
    stream_->MarkHeadersConsumed(headers.length());
    for (size_t offset = 0; offset < body.size(); offset += fragment_size) {
      size_t remaining_data = body.size() - offset;
      StringPiece fragment(body.data() + offset,
                           min(fragment_size, remaining_data));
      QuicStreamFrame frame(kClientDataStreamId1, false, offset,
                            StringPiece(fragment));
      stream_->OnStreamFrame(frame);
    }
    ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size;
  }
}

TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  string body = "this is the body";

  for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) {
    Initialize(kShouldProcessData);
    StringPiece headers1(headers.data(), split_point);
    stream_->OnStreamHeaders(headers1);

    StringPiece headers2(headers.data() + split_point,
                         headers.size() - split_point);
    stream_->OnStreamHeaders(headers2);
    stream_->OnStreamHeadersComplete(false, headers.size());
    ASSERT_EQ(headers, stream_->decompressed_headers())
        << "split_point: " << split_point;
    stream_->MarkHeadersConsumed(headers.length());

    StringPiece fragment1(body.data(), split_point);
    QuicStreamFrame frame1(kClientDataStreamId1, false, 0,
                           StringPiece(fragment1));
    stream_->OnStreamFrame(frame1);

    StringPiece fragment2(body.data() + split_point,
                          body.size() - split_point);
    QuicStreamFrame frame2(kClientDataStreamId1, false, split_point,
                           StringPiece(fragment2));
    stream_->OnStreamFrame(frame2);

    ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point;
  }
}

TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyReadv) {
  Initialize(!kShouldProcessData);

  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  string body = "this is the body";

  stream_->OnStreamHeaders(headers);
  stream_->OnStreamHeadersComplete(false, headers.size());
  QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body));
  stream_->OnStreamFrame(frame);
  stream_->MarkHeadersConsumed(headers.length());

  char buffer[2048];
  ASSERT_LT(body.length(), arraysize(buffer));
  struct iovec vec;
  vec.iov_base = buffer;
  vec.iov_len = arraysize(buffer);

  size_t bytes_read = stream_->Readv(&vec, 1);
  EXPECT_EQ(body.length(), bytes_read);
  EXPECT_EQ(body, string(buffer, bytes_read));
}

TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
  Initialize(!kShouldProcessData);

  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  string body = "this is the body";
  stream_->OnStreamHeaders(headers);
  stream_->OnStreamHeadersComplete(false, headers.size());
  QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body));
  stream_->OnStreamFrame(frame);
  stream_->MarkHeadersConsumed(headers.length());

  char buffer[1];
  struct iovec vec;
  vec.iov_base = buffer;
  vec.iov_len = arraysize(buffer);

  for (size_t i = 0; i < body.length(); ++i) {
    size_t bytes_read = stream_->Readv(&vec, 1);
    ASSERT_EQ(1u, bytes_read);
    EXPECT_EQ(body.data()[i], buffer[0]);
  }
}

TEST_P(QuicDataStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
  Initialize(!kShouldProcessData);

  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  string body = "this is the body";
  stream_->OnStreamHeaders(headers);
  stream_->OnStreamHeadersComplete(false, headers.size());
  QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body));
  stream_->OnStreamFrame(frame);
  stream_->MarkHeadersConsumed(headers.length());

  char buffer1[1];
  char buffer2[1];
  struct iovec vec[2];
  vec[0].iov_base = buffer1;
  vec[0].iov_len = arraysize(buffer1);
  vec[1].iov_base = buffer2;
  vec[1].iov_len = arraysize(buffer2);

  for (size_t i = 0; i < body.length(); i += 2) {
    size_t bytes_read = stream_->Readv(vec, 2);
    ASSERT_EQ(2u, bytes_read) << i;
    ASSERT_EQ(body.data()[i], buffer1[0]) << i;
    ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i;
  }
}

TEST_P(QuicDataStreamTest, StreamFlowControlBlocked) {
  // Tests that we send a BLOCKED frame to the peer when we attempt to write,
  // but are flow control blocked.
  Initialize(kShouldProcessData);

  // Set a small flow control limit.
  const uint64 kWindow = 36;
  QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(),
                                              kWindow);
  EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset(
                         stream_->flow_controller()));

  // Try to send more data than the flow control limit allows.
  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  string body;
  const uint64 kOverflow = 15;
  GenerateBody(&body, kWindow + kOverflow);

  EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1));
  EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _))
      .WillOnce(Return(QuicConsumedData(kWindow, true)));
  stream_->WriteOrBufferData(body, false, nullptr);

  // Should have sent as much as possible, resulting in no send window left.
  EXPECT_EQ(0u,
            QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller()));

  // And we should have queued the overflowed data.
  EXPECT_EQ(kOverflow,
            ReliableQuicStreamPeer::SizeOfQueuedData(stream_.get()));
}

TEST_P(QuicDataStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
  // The flow control receive window decreases whenever we add new bytes to the
  // sequencer, whether they are consumed immediately or buffered. However we
  // only send WINDOW_UPDATE frames based on increasing number of bytes
  // consumed.

  // Don't process data - it will be buffered instead.
  Initialize(!kShouldProcessData);

  // Expect no WINDOW_UPDATE frames to be sent.
  EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0);

  // Set a small flow control receive window.
  const uint64 kWindow = 36;
  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
                                                 kWindow);
  QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
                                              kWindow);
  EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset(
                         stream_->flow_controller()));

  // Stream receives enough data to fill a fraction of the receive window.
  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  string body;
  GenerateBody(&body, kWindow / 3);
  stream_->OnStreamHeaders(headers);
  stream_->OnStreamHeadersComplete(false, headers.size());

  QuicStreamFrame frame1(kClientDataStreamId1, false, 0, StringPiece(body));
  stream_->OnStreamFrame(frame1);
  EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize(
                                         stream_->flow_controller()));

  // Now receive another frame which results in the receive window being over
  // half full. This should all be buffered, decreasing the receive window but
  // not sending WINDOW_UPDATE.
  QuicStreamFrame frame2(kClientDataStreamId1, false, kWindow / 3,
                         StringPiece(body));
  stream_->OnStreamFrame(frame2);
  EXPECT_EQ(
      kWindow - (2 * kWindow / 3),
      QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller()));
}

TEST_P(QuicDataStreamTest, StreamFlowControlWindowUpdate) {
  // Tests that on receipt of data, the stream updates its receive window offset
  // appropriately, and sends WINDOW_UPDATE frames when its receive window drops
  // too low.
  Initialize(kShouldProcessData);

  // Set a small flow control limit.
  const uint64 kWindow = 36;
  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
                                                 kWindow);
  QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
                                              kWindow);
  EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset(
                         stream_->flow_controller()));

  // Stream receives enough data to fill a fraction of the receive window.
  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  string body;
  GenerateBody(&body, kWindow / 3);
  stream_->OnStreamHeaders(headers);
  stream_->OnStreamHeadersComplete(false, headers.size());
  stream_->MarkHeadersConsumed(headers.length());

  QuicStreamFrame frame1(kClientDataStreamId1, false, 0, StringPiece(body));
  stream_->OnStreamFrame(frame1);
  EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize(
                                         stream_->flow_controller()));

  // Now receive another frame which results in the receive window being over
  // half full.  This will trigger the stream to increase its receive window
  // offset and send a WINDOW_UPDATE. The result will be again an available
  // window of kWindow bytes.
  QuicStreamFrame frame2(kClientDataStreamId1, false, kWindow / 3,
                         StringPiece(body));
  EXPECT_CALL(*connection_,
              SendWindowUpdate(kClientDataStreamId1,
                               QuicFlowControllerPeer::ReceiveWindowOffset(
                                   stream_->flow_controller()) +
                                   2 * kWindow / 3));
  stream_->OnStreamFrame(frame2);
  EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize(
                         stream_->flow_controller()));
}

TEST_P(QuicDataStreamTest, ConnectionFlowControlWindowUpdate) {
  // Tests that on receipt of data, the connection updates its receive window
  // offset appropriately, and sends WINDOW_UPDATE frames when its receive
  // window drops too low.
  Initialize(kShouldProcessData);

  // Set a small flow control limit for streams and connection.
  const uint64 kWindow = 36;
  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
                                                 kWindow);
  QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
                                              kWindow);
  QuicFlowControllerPeer::SetReceiveWindowOffset(stream2_->flow_controller(),
                                                 kWindow);
  QuicFlowControllerPeer::SetMaxReceiveWindow(stream2_->flow_controller(),
                                              kWindow);
  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
                                                 kWindow);
  QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(),
                                              kWindow);

  // Supply headers to both streams so that they are happy to receive data.
  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  stream_->OnStreamHeaders(headers);
  stream_->OnStreamHeadersComplete(false, headers.size());
  stream_->MarkHeadersConsumed(headers.length());
  stream2_->OnStreamHeaders(headers);
  stream2_->OnStreamHeadersComplete(false, headers.size());
  stream2_->MarkHeadersConsumed(headers.length());

  // Each stream gets a quarter window of data. This should not trigger a
  // WINDOW_UPDATE for either stream, nor for the connection.
  string body;
  GenerateBody(&body, kWindow / 4);
  QuicStreamFrame frame1(kClientDataStreamId1, false, 0, StringPiece(body));
  stream_->OnStreamFrame(frame1);
  QuicStreamFrame frame2(kClientDataStreamId2, false, 0, StringPiece(body));
  stream2_->OnStreamFrame(frame2);

  // Now receive a further single byte on one stream - again this does not
  // trigger a stream WINDOW_UPDATE, but now the connection flow control window
  // is over half full and thus a connection WINDOW_UPDATE is sent.
  EXPECT_CALL(*connection_, SendWindowUpdate(kClientDataStreamId1, _)).Times(0);
  EXPECT_CALL(*connection_, SendWindowUpdate(kClientDataStreamId2, _)).Times(0);
  EXPECT_CALL(*connection_,
              SendWindowUpdate(0, QuicFlowControllerPeer::ReceiveWindowOffset(
                                      session_->flow_controller()) +
                                      1 + kWindow / 2));
  QuicStreamFrame frame3(kClientDataStreamId1, false, (kWindow / 4),
                         StringPiece("a"));
  stream_->OnStreamFrame(frame3);
}

TEST_P(QuicDataStreamTest, StreamFlowControlViolation) {
  // Tests that on if the peer sends too much data (i.e. violates the flow
  // control protocol), then we terminate the connection.

  // Stream should not process data, so that data gets buffered in the
  // sequencer, triggering flow control limits.
  Initialize(!kShouldProcessData);

  // Set a small flow control limit.
  const uint64 kWindow = 50;
  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
                                                 kWindow);

  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  stream_->OnStreamHeaders(headers);
  stream_->OnStreamHeadersComplete(false, headers.size());

  // Receive data to overflow the window, violating flow control.
  string body;
  GenerateBody(&body, kWindow + 1);
  QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body));
  EXPECT_CALL(*connection_,
              SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA));
  stream_->OnStreamFrame(frame);
}

TEST_P(QuicDataStreamTest, ConnectionFlowControlViolation) {
  // Tests that on if the peer sends too much data (i.e. violates the flow
  // control protocol), at the connection level (rather than the stream level)
  // then we terminate the connection.

  // Stream should not process data, so that data gets buffered in the
  // sequencer, triggering flow control limits.
  Initialize(!kShouldProcessData);

  // Set a small flow control window on streams, and connection.
  const uint64 kStreamWindow = 50;
  const uint64 kConnectionWindow = 10;
  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
                                                 kStreamWindow);
  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
                                                 kConnectionWindow);

  string headers =
      SpdyUtils::SerializeUncompressedHeaders(headers_, GetParam());
  stream_->OnStreamHeaders(headers);
  stream_->OnStreamHeadersComplete(false, headers.size());

  // Send enough data to overflow the connection level flow control window.
  string body;
  GenerateBody(&body, kConnectionWindow + 1);
  EXPECT_LT(body.size(),  kStreamWindow);
  QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body));

  EXPECT_CALL(*connection_,
              SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA));
  stream_->OnStreamFrame(frame);
}

TEST_P(QuicDataStreamTest, StreamFlowControlFinNotBlocked) {
  // An attempt to write a FIN with no data should not be flow control blocked,
  // even if the send window is 0.

  Initialize(kShouldProcessData);

  // Set a flow control limit of zero.
  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0);
  EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset(
                    stream_->flow_controller()));

  // Send a frame with a FIN but no data. This should not be blocked.
  string body = "";
  bool fin = true;

  EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)).Times(0);
  EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _))
      .WillOnce(Return(QuicConsumedData(0, fin)));

  stream_->WriteOrBufferData(body, fin, nullptr);
}

}  // namespace
}  // namespace test
}  // namespace net
