Home | History | Annotate | Download | only in quic
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/quic/quic_session.h"
      6 
      7 #include <set>
      8 #include <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/containers/hash_tables.h"
     12 #include "base/rand_util.h"
     13 #include "base/strings/string_number_conversions.h"
     14 #include "net/quic/crypto/crypto_protocol.h"
     15 #include "net/quic/quic_crypto_stream.h"
     16 #include "net/quic/quic_flags.h"
     17 #include "net/quic/quic_protocol.h"
     18 #include "net/quic/quic_utils.h"
     19 #include "net/quic/reliable_quic_stream.h"
     20 #include "net/quic/test_tools/quic_config_peer.h"
     21 #include "net/quic/test_tools/quic_connection_peer.h"
     22 #include "net/quic/test_tools/quic_data_stream_peer.h"
     23 #include "net/quic/test_tools/quic_flow_controller_peer.h"
     24 #include "net/quic/test_tools/quic_session_peer.h"
     25 #include "net/quic/test_tools/quic_test_utils.h"
     26 #include "net/quic/test_tools/reliable_quic_stream_peer.h"
     27 #include "net/spdy/spdy_framer.h"
     28 #include "net/test/gtest_util.h"
     29 #include "testing/gmock/include/gmock/gmock.h"
     30 #include "testing/gmock_mutant.h"
     31 #include "testing/gtest/include/gtest/gtest.h"
     32 
     33 using base::hash_map;
     34 using std::set;
     35 using std::vector;
     36 using testing::CreateFunctor;
     37 using testing::InSequence;
     38 using testing::Invoke;
     39 using testing::Return;
     40 using testing::StrictMock;
     41 using testing::_;
     42 
     43 namespace net {
     44 namespace test {
     45 namespace {
     46 
     47 const QuicPriority kHighestPriority = 0;
     48 const QuicPriority kSomeMiddlePriority = 3;
     49 
     50 class TestCryptoStream : public QuicCryptoStream {
     51  public:
     52   explicit TestCryptoStream(QuicSession* session)
     53       : QuicCryptoStream(session) {
     54   }
     55 
     56   virtual void OnHandshakeMessage(
     57       const CryptoHandshakeMessage& message) OVERRIDE {
     58     encryption_established_ = true;
     59     handshake_confirmed_ = true;
     60     CryptoHandshakeMessage msg;
     61     string error_details;
     62     session()->config()->SetInitialFlowControlWindowToSend(
     63         kInitialSessionFlowControlWindowForTest);
     64     session()->config()->SetInitialStreamFlowControlWindowToSend(
     65         kInitialStreamFlowControlWindowForTest);
     66     session()->config()->SetInitialSessionFlowControlWindowToSend(
     67         kInitialSessionFlowControlWindowForTest);
     68     session()->config()->ToHandshakeMessage(&msg);
     69     const QuicErrorCode error = session()->config()->ProcessPeerHello(
     70         msg, CLIENT, &error_details);
     71     EXPECT_EQ(QUIC_NO_ERROR, error);
     72     session()->OnConfigNegotiated();
     73     session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
     74   }
     75 
     76   MOCK_METHOD0(OnCanWrite, void());
     77 };
     78 
     79 class TestHeadersStream : public QuicHeadersStream {
     80  public:
     81   explicit TestHeadersStream(QuicSession* session)
     82       : QuicHeadersStream(session) {
     83   }
     84 
     85   MOCK_METHOD0(OnCanWrite, void());
     86 };
     87 
     88 class TestStream : public QuicDataStream {
     89  public:
     90   TestStream(QuicStreamId id, QuicSession* session)
     91       : QuicDataStream(id, session) {
     92   }
     93 
     94   using ReliableQuicStream::CloseWriteSide;
     95 
     96   virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE {
     97     return data_len;
     98   }
     99 
    100   void SendBody(const string& data, bool fin) {
    101     WriteOrBufferData(data, fin, NULL);
    102   }
    103 
    104   MOCK_METHOD0(OnCanWrite, void());
    105 };
    106 
    107 // Poor man's functor for use as callback in a mock.
    108 class StreamBlocker {
    109  public:
    110   StreamBlocker(QuicSession* session, QuicStreamId stream_id)
    111       : session_(session),
    112         stream_id_(stream_id) {
    113   }
    114 
    115   void MarkWriteBlocked() {
    116     session_->MarkWriteBlocked(stream_id_, kSomeMiddlePriority);
    117   }
    118 
    119  private:
    120   QuicSession* const session_;
    121   const QuicStreamId stream_id_;
    122 };
    123 
    124 class TestSession : public QuicSession {
    125  public:
    126   explicit TestSession(QuicConnection* connection)
    127       : QuicSession(connection,
    128                     DefaultQuicConfig()),
    129         crypto_stream_(this),
    130         writev_consumes_all_data_(false) {
    131     InitializeSession();
    132   }
    133 
    134   virtual TestCryptoStream* GetCryptoStream() OVERRIDE {
    135     return &crypto_stream_;
    136   }
    137 
    138   virtual TestStream* CreateOutgoingDataStream() OVERRIDE {
    139     TestStream* stream = new TestStream(GetNextStreamId(), this);
    140     ActivateStream(stream);
    141     return stream;
    142   }
    143 
    144   virtual TestStream* CreateIncomingDataStream(QuicStreamId id) OVERRIDE {
    145     return new TestStream(id, this);
    146   }
    147 
    148   bool IsClosedStream(QuicStreamId id) {
    149     return QuicSession::IsClosedStream(id);
    150   }
    151 
    152   QuicDataStream* GetIncomingDataStream(QuicStreamId stream_id) {
    153     return QuicSession::GetIncomingDataStream(stream_id);
    154   }
    155 
    156   virtual QuicConsumedData WritevData(
    157       QuicStreamId id,
    158       const IOVector& data,
    159       QuicStreamOffset offset,
    160       bool fin,
    161       FecProtection fec_protection,
    162       QuicAckNotifier::DelegateInterface* ack_notifier_delegate) OVERRIDE {
    163     // Always consumes everything.
    164     if (writev_consumes_all_data_) {
    165       return QuicConsumedData(data.TotalBufferSize(), fin);
    166     } else {
    167       return QuicSession::WritevData(id, data, offset, fin, fec_protection,
    168                                      ack_notifier_delegate);
    169     }
    170   }
    171 
    172   void set_writev_consumes_all_data(bool val) {
    173     writev_consumes_all_data_ = val;
    174   }
    175 
    176   QuicConsumedData SendStreamData(QuicStreamId id) {
    177     return WritevData(id, IOVector(), 0, true, MAY_FEC_PROTECT, NULL);
    178   }
    179 
    180   using QuicSession::PostProcessAfterData;
    181 
    182  private:
    183   StrictMock<TestCryptoStream> crypto_stream_;
    184 
    185   bool writev_consumes_all_data_;
    186 };
    187 
    188 class QuicSessionTest : public ::testing::TestWithParam<QuicVersion> {
    189  protected:
    190   QuicSessionTest()
    191       : connection_(new MockConnection(true, SupportedVersions(GetParam()))),
    192         session_(connection_) {
    193     session_.config()->SetInitialFlowControlWindowToSend(
    194         kInitialSessionFlowControlWindowForTest);
    195     session_.config()->SetInitialStreamFlowControlWindowToSend(
    196         kInitialStreamFlowControlWindowForTest);
    197     session_.config()->SetInitialSessionFlowControlWindowToSend(
    198         kInitialSessionFlowControlWindowForTest);
    199     headers_[":host"] = "www.google.com";
    200     headers_[":path"] = "/index.hml";
    201     headers_[":scheme"] = "http";
    202     headers_["cookie"] =
    203         "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
    204         "__utmc=160408618; "
    205         "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
    206         "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
    207         "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
    208         "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
    209         "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
    210         "1zFMi5vzcns38-8_Sns; "
    211         "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
    212         "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
    213         "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
    214         "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
    215         "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
    216         "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
    217         "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
    218         "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
    219         "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
    220         "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
    221         "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
    222         "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
    223         "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
    224         "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
    225         "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
    226   }
    227 
    228   void CheckClosedStreams() {
    229     for (int i = kCryptoStreamId; i < 100; i++) {
    230       if (closed_streams_.count(i) == 0) {
    231         EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
    232       } else {
    233         EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
    234       }
    235     }
    236   }
    237 
    238   void CloseStream(QuicStreamId id) {
    239     session_.CloseStream(id);
    240     closed_streams_.insert(id);
    241   }
    242 
    243   QuicVersion version() const { return connection_->version(); }
    244 
    245   MockConnection* connection_;
    246   TestSession session_;
    247   set<QuicStreamId> closed_streams_;
    248   SpdyHeaderBlock headers_;
    249 };
    250 
    251 INSTANTIATE_TEST_CASE_P(Tests, QuicSessionTest,
    252                         ::testing::ValuesIn(QuicSupportedVersions()));
    253 
    254 TEST_P(QuicSessionTest, PeerAddress) {
    255   EXPECT_EQ(IPEndPoint(Loopback4(), kTestPort), session_.peer_address());
    256 }
    257 
    258 TEST_P(QuicSessionTest, IsCryptoHandshakeConfirmed) {
    259   EXPECT_FALSE(session_.IsCryptoHandshakeConfirmed());
    260   CryptoHandshakeMessage message;
    261   session_.GetCryptoStream()->OnHandshakeMessage(message);
    262   EXPECT_TRUE(session_.IsCryptoHandshakeConfirmed());
    263 }
    264 
    265 TEST_P(QuicSessionTest, IsClosedStreamDefault) {
    266   // Ensure that no streams are initially closed.
    267   for (int i = kCryptoStreamId; i < 100; i++) {
    268     EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
    269   }
    270 }
    271 
    272 TEST_P(QuicSessionTest, ImplicitlyCreatedStreams) {
    273   ASSERT_TRUE(session_.GetIncomingDataStream(7) != NULL);
    274   // Both 3 and 5 should be implicitly created.
    275   EXPECT_FALSE(session_.IsClosedStream(3));
    276   EXPECT_FALSE(session_.IsClosedStream(5));
    277   ASSERT_TRUE(session_.GetIncomingDataStream(5) != NULL);
    278   ASSERT_TRUE(session_.GetIncomingDataStream(3) != NULL);
    279 }
    280 
    281 TEST_P(QuicSessionTest, IsClosedStreamLocallyCreated) {
    282   TestStream* stream2 = session_.CreateOutgoingDataStream();
    283   EXPECT_EQ(2u, stream2->id());
    284   TestStream* stream4 = session_.CreateOutgoingDataStream();
    285   EXPECT_EQ(4u, stream4->id());
    286 
    287   CheckClosedStreams();
    288   CloseStream(4);
    289   CheckClosedStreams();
    290   CloseStream(2);
    291   CheckClosedStreams();
    292 }
    293 
    294 TEST_P(QuicSessionTest, IsClosedStreamPeerCreated) {
    295   QuicStreamId stream_id1 = kClientDataStreamId1;
    296   QuicStreamId stream_id2 = kClientDataStreamId2;
    297   QuicDataStream* stream1 = session_.GetIncomingDataStream(stream_id1);
    298   QuicDataStreamPeer::SetHeadersDecompressed(stream1, true);
    299   QuicDataStream* stream2 = session_.GetIncomingDataStream(stream_id2);
    300   QuicDataStreamPeer::SetHeadersDecompressed(stream2, true);
    301 
    302   CheckClosedStreams();
    303   CloseStream(stream_id1);
    304   CheckClosedStreams();
    305   CloseStream(stream_id2);
    306   // Create a stream explicitly, and another implicitly.
    307   QuicDataStream* stream3 = session_.GetIncomingDataStream(stream_id2 + 4);
    308   QuicDataStreamPeer::SetHeadersDecompressed(stream3, true);
    309   CheckClosedStreams();
    310   // Close one, but make sure the other is still not closed
    311   CloseStream(stream3->id());
    312   CheckClosedStreams();
    313 }
    314 
    315 TEST_P(QuicSessionTest, StreamIdTooLarge) {
    316   QuicStreamId stream_id = kClientDataStreamId1;
    317   session_.GetIncomingDataStream(stream_id);
    318   EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID));
    319   session_.GetIncomingDataStream(stream_id + kMaxStreamIdDelta + 2);
    320 }
    321 
    322 TEST_P(QuicSessionTest, DecompressionError) {
    323   QuicHeadersStream* stream = QuicSessionPeer::GetHeadersStream(&session_);
    324   const unsigned char data[] = {
    325     0x80, 0x03, 0x00, 0x01,  // SPDY/3 SYN_STREAM frame
    326     0x00, 0x00, 0x00, 0x25,  // flags/length
    327     0x00, 0x00, 0x00, 0x05,  // stream id
    328     0x00, 0x00, 0x00, 0x00,  // associated stream id
    329     0x00, 0x00,
    330     'a',  'b',  'c',  'd'    // invalid compressed data
    331   };
    332   EXPECT_CALL(*connection_,
    333               SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
    334                                              "SPDY framing error."));
    335   stream->ProcessRawData(reinterpret_cast<const char*>(data),
    336                          arraysize(data));
    337 }
    338 
    339 TEST_P(QuicSessionTest, DebugDFatalIfMarkingClosedStreamWriteBlocked) {
    340   TestStream* stream2 = session_.CreateOutgoingDataStream();
    341   // Close the stream.
    342   stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
    343   // TODO(rtenneti): enable when chromium supports EXPECT_DEBUG_DFATAL.
    344   /*
    345   QuicStreamId kClosedStreamId = stream2->id();
    346   EXPECT_DEBUG_DFATAL(
    347       session_.MarkWriteBlocked(kClosedStreamId, kSomeMiddlePriority),
    348       "Marking unknown stream 2 blocked.");
    349   */
    350 }
    351 
    352 TEST_P(QuicSessionTest, DebugDFatalIfMarkWriteBlockedCalledWithWrongPriority) {
    353   const QuicPriority kDifferentPriority = 0;
    354 
    355   TestStream* stream2 = session_.CreateOutgoingDataStream();
    356   EXPECT_NE(kDifferentPriority, stream2->EffectivePriority());
    357   // TODO(rtenneti): enable when chromium supports EXPECT_DEBUG_DFATAL.
    358   /*
    359   EXPECT_DEBUG_DFATAL(
    360       session_.MarkWriteBlocked(stream2->id(), kDifferentPriority),
    361       "Priorities do not match.  Got: 0 Expected: 3");
    362   */
    363 }
    364 
    365 TEST_P(QuicSessionTest, OnCanWrite) {
    366   TestStream* stream2 = session_.CreateOutgoingDataStream();
    367   TestStream* stream4 = session_.CreateOutgoingDataStream();
    368   TestStream* stream6 = session_.CreateOutgoingDataStream();
    369 
    370   session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority);
    371   session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority);
    372   session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority);
    373 
    374   InSequence s;
    375   StreamBlocker stream2_blocker(&session_, stream2->id());
    376   // Reregister, to test the loop limit.
    377   EXPECT_CALL(*stream2, OnCanWrite())
    378       .WillOnce(Invoke(&stream2_blocker, &StreamBlocker::MarkWriteBlocked));
    379   EXPECT_CALL(*stream6, OnCanWrite());
    380   EXPECT_CALL(*stream4, OnCanWrite());
    381   session_.OnCanWrite();
    382   EXPECT_TRUE(session_.WillingAndAbleToWrite());
    383 }
    384 
    385 TEST_P(QuicSessionTest, OnCanWriteBundlesStreams) {
    386   // Drive congestion control manually.
    387   MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
    388   QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
    389 
    390   TestStream* stream2 = session_.CreateOutgoingDataStream();
    391   TestStream* stream4 = session_.CreateOutgoingDataStream();
    392   TestStream* stream6 = session_.CreateOutgoingDataStream();
    393 
    394   session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority);
    395   session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority);
    396   session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority);
    397 
    398   EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillRepeatedly(
    399       Return(QuicTime::Delta::Zero()));
    400   EXPECT_CALL(*send_algorithm, GetCongestionWindow())
    401       .WillOnce(Return(kMaxPacketSize * 10));
    402   EXPECT_CALL(*stream2, OnCanWrite())
    403       .WillOnce(IgnoreResult(Invoke(CreateFunctor(
    404           &session_, &TestSession::SendStreamData, stream2->id()))));
    405   EXPECT_CALL(*stream4, OnCanWrite())
    406       .WillOnce(IgnoreResult(Invoke(CreateFunctor(
    407           &session_, &TestSession::SendStreamData, stream4->id()))));
    408   EXPECT_CALL(*stream6, OnCanWrite())
    409       .WillOnce(IgnoreResult(Invoke(CreateFunctor(
    410           &session_, &TestSession::SendStreamData, stream6->id()))));
    411 
    412   // Expect that we only send one packet, the writes from different streams
    413   // should be bundled together.
    414   MockPacketWriter* writer =
    415       static_cast<MockPacketWriter*>(
    416           QuicConnectionPeer::GetWriter(session_.connection()));
    417   EXPECT_CALL(*writer, WritePacket(_, _, _, _)).WillOnce(
    418                   Return(WriteResult(WRITE_STATUS_OK, 0)));
    419   EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _)).Times(1);
    420   session_.OnCanWrite();
    421   EXPECT_FALSE(session_.WillingAndAbleToWrite());
    422 }
    423 
    424 TEST_P(QuicSessionTest, OnCanWriteCongestionControlBlocks) {
    425   InSequence s;
    426 
    427   // Drive congestion control manually.
    428   MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
    429   QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
    430 
    431   TestStream* stream2 = session_.CreateOutgoingDataStream();
    432   TestStream* stream4 = session_.CreateOutgoingDataStream();
    433   TestStream* stream6 = session_.CreateOutgoingDataStream();
    434 
    435   session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority);
    436   session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority);
    437   session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority);
    438 
    439   StreamBlocker stream2_blocker(&session_, stream2->id());
    440   EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
    441       QuicTime::Delta::Zero()));
    442   EXPECT_CALL(*stream2, OnCanWrite());
    443   EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
    444       QuicTime::Delta::Zero()));
    445   EXPECT_CALL(*stream6, OnCanWrite());
    446   EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
    447       QuicTime::Delta::Infinite()));
    448   // stream4->OnCanWrite is not called.
    449 
    450   session_.OnCanWrite();
    451   EXPECT_TRUE(session_.WillingAndAbleToWrite());
    452 
    453   // Still congestion-control blocked.
    454   EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
    455       QuicTime::Delta::Infinite()));
    456   session_.OnCanWrite();
    457   EXPECT_TRUE(session_.WillingAndAbleToWrite());
    458 
    459   // stream4->OnCanWrite is called once the connection stops being
    460   // congestion-control blocked.
    461   EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
    462       QuicTime::Delta::Zero()));
    463   EXPECT_CALL(*stream4, OnCanWrite());
    464   session_.OnCanWrite();
    465   EXPECT_FALSE(session_.WillingAndAbleToWrite());
    466 }
    467 
    468 TEST_P(QuicSessionTest, BufferedHandshake) {
    469   EXPECT_FALSE(session_.HasPendingHandshake());  // Default value.
    470 
    471   // Test that blocking other streams does not change our status.
    472   TestStream* stream2 = session_.CreateOutgoingDataStream();
    473   StreamBlocker stream2_blocker(&session_, stream2->id());
    474   stream2_blocker.MarkWriteBlocked();
    475   EXPECT_FALSE(session_.HasPendingHandshake());
    476 
    477   TestStream* stream3 = session_.CreateOutgoingDataStream();
    478   StreamBlocker stream3_blocker(&session_, stream3->id());
    479   stream3_blocker.MarkWriteBlocked();
    480   EXPECT_FALSE(session_.HasPendingHandshake());
    481 
    482   // Blocking (due to buffering of) the Crypto stream is detected.
    483   session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority);
    484   EXPECT_TRUE(session_.HasPendingHandshake());
    485 
    486   TestStream* stream4 = session_.CreateOutgoingDataStream();
    487   StreamBlocker stream4_blocker(&session_, stream4->id());
    488   stream4_blocker.MarkWriteBlocked();
    489   EXPECT_TRUE(session_.HasPendingHandshake());
    490 
    491   InSequence s;
    492   // Force most streams to re-register, which is common scenario when we block
    493   // the Crypto stream, and only the crypto stream can "really" write.
    494 
    495   // Due to prioritization, we *should* be asked to write the crypto stream
    496   // first.
    497   // Don't re-register the crypto stream (which signals complete writing).
    498   TestCryptoStream* crypto_stream = session_.GetCryptoStream();
    499   EXPECT_CALL(*crypto_stream, OnCanWrite());
    500 
    501   // Re-register all other streams, to show they weren't able to proceed.
    502   EXPECT_CALL(*stream2, OnCanWrite())
    503       .WillOnce(Invoke(&stream2_blocker, &StreamBlocker::MarkWriteBlocked));
    504   EXPECT_CALL(*stream3, OnCanWrite())
    505       .WillOnce(Invoke(&stream3_blocker, &StreamBlocker::MarkWriteBlocked));
    506   EXPECT_CALL(*stream4, OnCanWrite())
    507       .WillOnce(Invoke(&stream4_blocker, &StreamBlocker::MarkWriteBlocked));
    508 
    509   session_.OnCanWrite();
    510   EXPECT_TRUE(session_.WillingAndAbleToWrite());
    511   EXPECT_FALSE(session_.HasPendingHandshake());  // Crypto stream wrote.
    512 }
    513 
    514 TEST_P(QuicSessionTest, OnCanWriteWithClosedStream) {
    515   TestStream* stream2 = session_.CreateOutgoingDataStream();
    516   TestStream* stream4 = session_.CreateOutgoingDataStream();
    517   TestStream* stream6 = session_.CreateOutgoingDataStream();
    518 
    519   session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority);
    520   session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority);
    521   session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority);
    522   CloseStream(stream6->id());
    523 
    524   InSequence s;
    525   EXPECT_CALL(*stream2, OnCanWrite());
    526   EXPECT_CALL(*stream4, OnCanWrite());
    527   session_.OnCanWrite();
    528   EXPECT_FALSE(session_.WillingAndAbleToWrite());
    529 }
    530 
    531 TEST_P(QuicSessionTest, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
    532   if (version() < QUIC_VERSION_19) {
    533     return;
    534   }
    535 
    536   // Ensure connection level flow control blockage.
    537   QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
    538   EXPECT_TRUE(session_.flow_controller()->IsBlocked());
    539 
    540   // Mark the crypto and headers streams as write blocked, we expect them to be
    541   // allowed to write later.
    542   session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority);
    543   session_.MarkWriteBlocked(kHeadersStreamId, kHighestPriority);
    544 
    545   // Create a data stream, and although it is write blocked we never expect it
    546   // to be allowed to write as we are connection level flow control blocked.
    547   TestStream* stream = session_.CreateOutgoingDataStream();
    548   session_.MarkWriteBlocked(stream->id(), kSomeMiddlePriority);
    549   EXPECT_CALL(*stream, OnCanWrite()).Times(0);
    550 
    551   // The crypto and headers streams should be called even though we are
    552   // connection flow control blocked.
    553   TestCryptoStream* crypto_stream = session_.GetCryptoStream();
    554   EXPECT_CALL(*crypto_stream, OnCanWrite()).Times(1);
    555   TestHeadersStream* headers_stream = new TestHeadersStream(&session_);
    556   QuicSessionPeer::SetHeadersStream(&session_, headers_stream);
    557   EXPECT_CALL(*headers_stream, OnCanWrite()).Times(1);
    558 
    559   session_.OnCanWrite();
    560   EXPECT_FALSE(session_.WillingAndAbleToWrite());
    561 }
    562 
    563 TEST_P(QuicSessionTest, SendGoAway) {
    564   EXPECT_CALL(*connection_,
    565               SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away."));
    566   session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
    567   EXPECT_TRUE(session_.goaway_sent());
    568 
    569   EXPECT_CALL(*connection_,
    570               SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY, 0)).Times(0);
    571   EXPECT_TRUE(session_.GetIncomingDataStream(3u));
    572 }
    573 
    574 TEST_P(QuicSessionTest, DoNotSendGoAwayTwice) {
    575   EXPECT_CALL(*connection_,
    576               SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")).Times(1);
    577   session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
    578   EXPECT_TRUE(session_.goaway_sent());
    579   session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
    580 }
    581 
    582 TEST_P(QuicSessionTest, IncreasedTimeoutAfterCryptoHandshake) {
    583   // Add 1 to the connection timeout on the server side.
    584   EXPECT_EQ(kDefaultInitialTimeoutSecs + 1,
    585             QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
    586   CryptoHandshakeMessage msg;
    587   session_.GetCryptoStream()->OnHandshakeMessage(msg);
    588   EXPECT_EQ(kMaximumIdleTimeoutSecs + 1,
    589             QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
    590 }
    591 
    592 TEST_P(QuicSessionTest, RstStreamBeforeHeadersDecompressed) {
    593   // Send two bytes of payload.
    594   QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT"));
    595   vector<QuicStreamFrame> frames;
    596   frames.push_back(data1);
    597   session_.OnStreamFrames(frames);
    598   EXPECT_EQ(1u, session_.GetNumOpenStreams());
    599 
    600   QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
    601   session_.OnRstStream(rst1);
    602   EXPECT_EQ(0u, session_.GetNumOpenStreams());
    603   // Connection should remain alive.
    604   EXPECT_TRUE(connection_->connected());
    605 }
    606 
    607 TEST_P(QuicSessionTest, MultipleRstStreamsCauseSingleConnectionClose) {
    608   // If multiple invalid reset stream frames arrive in a single packet, this
    609   // should trigger a connection close. However there is no need to send
    610   // multiple connection close frames.
    611 
    612   // Create valid stream.
    613   QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT"));
    614   vector<QuicStreamFrame> frames;
    615   frames.push_back(data1);
    616   session_.OnStreamFrames(frames);
    617   EXPECT_EQ(1u, session_.GetNumOpenStreams());
    618 
    619   // Process first invalid stream reset, resulting in the connection being
    620   // closed.
    621   EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID))
    622       .Times(1);
    623   QuicStreamId kLargeInvalidStreamId = 99999999;
    624   QuicRstStreamFrame rst1(kLargeInvalidStreamId, QUIC_STREAM_NO_ERROR, 0);
    625   session_.OnRstStream(rst1);
    626   QuicConnectionPeer::CloseConnection(connection_);
    627 
    628   // Processing of second invalid stream reset should not result in the
    629   // connection being closed for a second time.
    630   QuicRstStreamFrame rst2(kLargeInvalidStreamId, QUIC_STREAM_NO_ERROR, 0);
    631   session_.OnRstStream(rst2);
    632 }
    633 
    634 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedStream) {
    635   // Test that if a stream is flow control blocked, then on receipt of the SHLO
    636   // containing a suitable send window offset, the stream becomes unblocked.
    637   if (version() <= QUIC_VERSION_16) {
    638     return;
    639   }
    640 
    641   // Ensure that Writev consumes all the data it is given (simulate no socket
    642   // blocking).
    643   session_.set_writev_consumes_all_data(true);
    644 
    645   // Create a stream, and send enough data to make it flow control blocked.
    646   TestStream* stream2 = session_.CreateOutgoingDataStream();
    647   string body(kDefaultFlowControlSendWindow, '.');
    648   EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
    649   stream2->SendBody(body, false);
    650   EXPECT_TRUE(stream2->flow_controller()->IsBlocked());
    651 
    652   // The handshake message will call OnCanWrite, so the stream can resume
    653   // writing.
    654   EXPECT_CALL(*stream2, OnCanWrite());
    655   // Now complete the crypto handshake, resulting in an increased flow control
    656   // send window.
    657   CryptoHandshakeMessage msg;
    658   session_.GetCryptoStream()->OnHandshakeMessage(msg);
    659 
    660   // Stream is now unblocked.
    661   EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
    662 }
    663 
    664 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedCryptoStream) {
    665   if (version() <= QUIC_VERSION_19) {
    666     return;
    667   }
    668   // Test that if the crypto stream is flow control blocked, then if the SHLO
    669   // contains a larger send window offset, the stream becomes unblocked.
    670   session_.set_writev_consumes_all_data(true);
    671   TestCryptoStream* crypto_stream = session_.GetCryptoStream();
    672   EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
    673   QuicHeadersStream* headers_stream =
    674         QuicSessionPeer::GetHeadersStream(&session_);
    675   EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
    676   // Write until the crypto stream is flow control blocked.
    677   int i = 0;
    678   while (!crypto_stream->flow_controller()->IsBlocked() && i < 1000) {
    679     QuicConfig config;
    680     CryptoHandshakeMessage crypto_message;
    681     config.ToHandshakeMessage(&crypto_message);
    682     crypto_stream->SendHandshakeMessage(crypto_message);
    683     ++i;
    684   }
    685   EXPECT_TRUE(crypto_stream->flow_controller()->IsBlocked());
    686   EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
    687   EXPECT_FALSE(session_.HasDataToWrite());
    688   EXPECT_TRUE(crypto_stream->HasBufferedData());
    689 
    690   // The handshake message will call OnCanWrite, so the stream can
    691   // resume writing.
    692   EXPECT_CALL(*crypto_stream, OnCanWrite());
    693   // Now complete the crypto handshake, resulting in an increased flow control
    694   // send window.
    695   CryptoHandshakeMessage msg;
    696   session_.GetCryptoStream()->OnHandshakeMessage(msg);
    697 
    698   // Stream is now unblocked and will no longer have buffered data.
    699   EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
    700 }
    701 
    702 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedHeadersStream) {
    703   if (version() <= QUIC_VERSION_19) {
    704     return;
    705   }
    706   // Test that if the header stream is flow control blocked, then if the SHLO
    707   // contains a larger send window offset, the stream becomes unblocked.
    708   session_.set_writev_consumes_all_data(true);
    709   TestCryptoStream* crypto_stream = session_.GetCryptoStream();
    710   EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
    711   QuicHeadersStream* headers_stream =
    712       QuicSessionPeer::GetHeadersStream(&session_);
    713   EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
    714   QuicStreamId stream_id = 5;
    715   // Write until the header stream is flow control blocked.
    716   while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) {
    717     SpdyHeaderBlock headers;
    718     headers["header"] = base::Uint64ToString(base::RandUint64()) +
    719         base::Uint64ToString(base::RandUint64()) +
    720         base::Uint64ToString(base::RandUint64());
    721     headers_stream->WriteHeaders(stream_id, headers, true, nullptr);
    722     stream_id += 2;
    723   }
    724   EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked());
    725   EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
    726   EXPECT_FALSE(session_.HasDataToWrite());
    727   EXPECT_TRUE(headers_stream->HasBufferedData());
    728 
    729   // Now complete the crypto handshake, resulting in an increased flow control
    730   // send window.
    731   CryptoHandshakeMessage msg;
    732   session_.GetCryptoStream()->OnHandshakeMessage(msg);
    733 
    734   // Stream is now unblocked and will no longer have buffered data.
    735   EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
    736   EXPECT_FALSE(headers_stream->HasBufferedData());
    737 }
    738 
    739 TEST_P(QuicSessionTest, InvalidFlowControlWindowInHandshake) {
    740   // TODO(rjshade): Remove this test when removing QUIC_VERSION_19.
    741   // Test that receipt of an invalid (< default) flow control window from
    742   // the peer results in the connection being torn down.
    743   if (version() <= QUIC_VERSION_16 || version() > QUIC_VERSION_19) {
    744     return;
    745   }
    746 
    747   uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1;
    748   QuicConfigPeer::SetReceivedInitialFlowControlWindow(session_.config(),
    749                                                       kInvalidWindow);
    750 
    751   EXPECT_CALL(*connection_,
    752               SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)).Times(2);
    753   session_.OnConfigNegotiated();
    754 }
    755 
    756 TEST_P(QuicSessionTest, InvalidStreamFlowControlWindowInHandshake) {
    757   // Test that receipt of an invalid (< default) stream flow control window from
    758   // the peer results in the connection being torn down.
    759   if (version() <= QUIC_VERSION_19) {
    760     return;
    761   }
    762 
    763   uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1;
    764   QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
    765                                                             kInvalidWindow);
    766 
    767   EXPECT_CALL(*connection_,
    768               SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW));
    769   session_.OnConfigNegotiated();
    770 }
    771 
    772 TEST_P(QuicSessionTest, InvalidSessionFlowControlWindowInHandshake) {
    773   // Test that receipt of an invalid (< default) session flow control window
    774   // from the peer results in the connection being torn down.
    775   if (version() <= QUIC_VERSION_19) {
    776     return;
    777   }
    778 
    779   uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1;
    780   QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(),
    781                                                              kInvalidWindow);
    782 
    783   EXPECT_CALL(*connection_,
    784               SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW));
    785   session_.OnConfigNegotiated();
    786 }
    787 
    788 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstOutOfOrder) {
    789   if (version() < QUIC_VERSION_19) {
    790     return;
    791   }
    792 
    793   // Test that when we receive an out of order stream RST we correctly adjust
    794   // our connection level flow control receive window.
    795   // On close, the stream should mark as consumed all bytes between the highest
    796   // byte consumed so far and the final byte offset from the RST frame.
    797   TestStream* stream = session_.CreateOutgoingDataStream();
    798 
    799   const QuicStreamOffset kByteOffset =
    800       1 + kInitialSessionFlowControlWindowForTest / 2;
    801 
    802   // Expect no stream WINDOW_UPDATE frames, as stream read side closed.
    803   EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0);
    804   // We do expect a connection level WINDOW_UPDATE when the stream is reset.
    805   EXPECT_CALL(*connection_,
    806               SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest +
    807                                       kByteOffset)).Times(1);
    808 
    809   QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED,
    810                                kByteOffset);
    811   session_.OnRstStream(rst_frame);
    812   session_.PostProcessAfterData();
    813   EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
    814 }
    815 
    816 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAndLocalReset) {
    817   if (version() < QUIC_VERSION_19) {
    818     return;
    819   }
    820 
    821   // Test the situation where we receive a FIN on a stream, and before we fully
    822   // consume all the data from the sequencer buffer we locally RST the stream.
    823   // The bytes between highest consumed byte, and the final byte offset that we
    824   // determined when the FIN arrived, should be marked as consumed at the
    825   // connection level flow controller when the stream is reset.
    826   TestStream* stream = session_.CreateOutgoingDataStream();
    827 
    828   const QuicStreamOffset kByteOffset =
    829       1 + kInitialSessionFlowControlWindowForTest / 2;
    830   QuicStreamFrame frame(stream->id(), true, kByteOffset, IOVector());
    831   vector<QuicStreamFrame> frames;
    832   frames.push_back(frame);
    833   session_.OnStreamFrames(frames);
    834   session_.PostProcessAfterData();
    835 
    836   EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed());
    837   EXPECT_EQ(kByteOffset,
    838             stream->flow_controller()->highest_received_byte_offset());
    839 
    840   // We only expect to see a connection WINDOW_UPDATE when talking
    841   // QUIC_VERSION_19, as in this case both stream and session flow control
    842   // windows are the same size. In later versions we will not see a connection
    843   // level WINDOW_UPDATE when exhausting a stream, as the stream flow control
    844   // limit is much lower than the connection flow control limit.
    845   if (version() == QUIC_VERSION_19) {
    846     // Expect no stream WINDOW_UPDATE frames, as stream read side closed.
    847     EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0);
    848     // We do expect a connection level WINDOW_UPDATE when the stream is reset.
    849     EXPECT_CALL(*connection_,
    850                 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest +
    851                                         kByteOffset)).Times(1);
    852   }
    853 
    854   // Reset stream locally.
    855   stream->Reset(QUIC_STREAM_CANCELLED);
    856   EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
    857 }
    858 
    859 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAfterRst) {
    860   // Test that when we RST the stream (and tear down stream state), and then
    861   // receive a FIN from the peer, we correctly adjust our connection level flow
    862   // control receive window.
    863   if (version() < QUIC_VERSION_19) {
    864     return;
    865   }
    866 
    867   // Connection starts with some non-zero highest received byte offset,
    868   // due to other active streams.
    869   const uint64 kInitialConnectionBytesConsumed = 567;
    870   const uint64 kInitialConnectionHighestReceivedOffset = 1234;
    871   EXPECT_LT(kInitialConnectionBytesConsumed,
    872             kInitialConnectionHighestReceivedOffset);
    873   session_.flow_controller()->UpdateHighestReceivedOffset(
    874       kInitialConnectionHighestReceivedOffset);
    875   session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
    876 
    877   // Reset our stream: this results in the stream being closed locally.
    878   TestStream* stream = session_.CreateOutgoingDataStream();
    879   stream->Reset(QUIC_STREAM_CANCELLED);
    880 
    881   // Now receive a response from the peer with a FIN. We should handle this by
    882   // adjusting the connection level flow control receive window to take into
    883   // account the total number of bytes sent by the peer.
    884   const QuicStreamOffset kByteOffset = 5678;
    885   string body = "hello";
    886   IOVector data = MakeIOVector(body);
    887   QuicStreamFrame frame(stream->id(), true, kByteOffset, data);
    888   vector<QuicStreamFrame> frames;
    889   frames.push_back(frame);
    890   session_.OnStreamFrames(frames);
    891 
    892   QuicStreamOffset total_stream_bytes_sent_by_peer =
    893       kByteOffset + body.length();
    894   EXPECT_EQ(kInitialConnectionBytesConsumed + total_stream_bytes_sent_by_peer,
    895             session_.flow_controller()->bytes_consumed());
    896   EXPECT_EQ(
    897       kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer,
    898       session_.flow_controller()->highest_received_byte_offset());
    899 }
    900 
    901 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstAfterRst) {
    902   // Test that when we RST the stream (and tear down stream state), and then
    903   // receive a RST from the peer, we correctly adjust our connection level flow
    904   // control receive window.
    905   if (version() < QUIC_VERSION_19) {
    906     return;
    907   }
    908 
    909   // Connection starts with some non-zero highest received byte offset,
    910   // due to other active streams.
    911   const uint64 kInitialConnectionBytesConsumed = 567;
    912   const uint64 kInitialConnectionHighestReceivedOffset = 1234;
    913   EXPECT_LT(kInitialConnectionBytesConsumed,
    914             kInitialConnectionHighestReceivedOffset);
    915   session_.flow_controller()->UpdateHighestReceivedOffset(
    916       kInitialConnectionHighestReceivedOffset);
    917   session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
    918 
    919   // Reset our stream: this results in the stream being closed locally.
    920   TestStream* stream = session_.CreateOutgoingDataStream();
    921   stream->Reset(QUIC_STREAM_CANCELLED);
    922 
    923   // Now receive a RST from the peer. We should handle this by adjusting the
    924   // connection level flow control receive window to take into account the total
    925   // number of bytes sent by the peer.
    926   const QuicStreamOffset kByteOffset = 5678;
    927   QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED,
    928                                kByteOffset);
    929   session_.OnRstStream(rst_frame);
    930 
    931   EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset,
    932             session_.flow_controller()->bytes_consumed());
    933   EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset,
    934             session_.flow_controller()->highest_received_byte_offset());
    935 }
    936 
    937 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) {
    938   // Test that if we receive a stream RST with a highest byte offset that
    939   // violates flow control, that we close the connection.
    940   if (version() <= QUIC_VERSION_16) {
    941     return;
    942   }
    943 
    944   const uint64 kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
    945   EXPECT_CALL(*connection_,
    946               SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA))
    947       .Times(2);
    948 
    949   // Check that stream frame + FIN results in connection close.
    950   TestStream* stream = session_.CreateOutgoingDataStream();
    951   stream->Reset(QUIC_STREAM_CANCELLED);
    952   QuicStreamFrame frame(stream->id(), true, kLargeOffset, IOVector());
    953   vector<QuicStreamFrame> frames;
    954   frames.push_back(frame);
    955   session_.OnStreamFrames(frames);
    956 
    957   // Check that RST results in connection close.
    958   QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED,
    959                                kLargeOffset);
    960   session_.OnRstStream(rst_frame);
    961 }
    962 
    963 TEST_P(QuicSessionTest, VersionNegotiationDisablesFlowControl) {
    964   if (version() < QUIC_VERSION_19) {
    965     return;
    966   }
    967 
    968   // Test that after successful version negotiation, flow control is disabled
    969   // appropriately at both the connection and stream level.
    970 
    971   // Initially both stream and connection flow control are enabled.
    972   TestStream* stream = session_.CreateOutgoingDataStream();
    973   EXPECT_TRUE(stream->flow_controller()->IsEnabled());
    974   EXPECT_TRUE(session_.flow_controller()->IsEnabled());
    975 
    976   // Version 18 implies that stream flow control is enabled, but connection
    977   // level is disabled.
    978   session_.OnSuccessfulVersionNegotiation(QUIC_VERSION_18);
    979   EXPECT_FALSE(session_.flow_controller()->IsEnabled());
    980   EXPECT_TRUE(stream->flow_controller()->IsEnabled());
    981 
    982   // Version 16 means all flow control is disabled.
    983   session_.OnSuccessfulVersionNegotiation(QUIC_VERSION_16);
    984   EXPECT_FALSE(session_.flow_controller()->IsEnabled());
    985   EXPECT_FALSE(stream->flow_controller()->IsEnabled());
    986 }
    987 
    988 TEST_P(QuicSessionTest, WindowUpdateUnblocksHeadersStream) {
    989   // Test that a flow control blocked headers stream gets unblocked on recipt of
    990   // a WINDOW_UPDATE frame. Regression test for b/17413860.
    991   if (version() < QUIC_VERSION_21) {
    992     return;
    993   }
    994 
    995   // Set the headers stream to be flow control blocked.
    996   QuicHeadersStream* headers_stream =
    997       QuicSessionPeer::GetHeadersStream(&session_);
    998   QuicFlowControllerPeer::SetSendWindowOffset(headers_stream->flow_controller(),
    999                                               0);
   1000   EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked());
   1001 
   1002   // Unblock the headers stream by supplying a WINDOW_UPDATE.
   1003   QuicWindowUpdateFrame window_update_frame(headers_stream->id(),
   1004                                             2 * kDefaultFlowControlSendWindow);
   1005   vector<QuicWindowUpdateFrame> frames;
   1006   frames.push_back(window_update_frame);
   1007   session_.OnWindowUpdateFrames(frames);
   1008   EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
   1009 }
   1010 
   1011 TEST_P(QuicSessionTest, TooManyUnfinishedStreamsCauseConnectionClose) {
   1012   if (version() < QUIC_VERSION_18) {
   1013     return;
   1014   }
   1015   // If a buggy/malicious peer creates too many streams that are not ended with
   1016   // a FIN or RST then we send a connection close.
   1017   ValueRestore<bool> old_flag(&FLAGS_close_quic_connection_unfinished_streams_2,
   1018                               true);
   1019 
   1020   EXPECT_CALL(*connection_,
   1021               SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS)).Times(1);
   1022 
   1023   const int kMaxStreams = 5;
   1024   QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams);
   1025 
   1026   // Create kMaxStreams + 1 data streams, and close them all without receiving a
   1027   // FIN or a RST from the client.
   1028   const int kFirstStreamId = kClientDataStreamId1;
   1029   const int kFinalStreamId = kClientDataStreamId1 + 2 * kMaxStreams + 1;
   1030   for (int i = kFirstStreamId; i < kFinalStreamId; i += 2) {
   1031     QuicStreamFrame data1(i, false, 0, MakeIOVector("HT"));
   1032     vector<QuicStreamFrame> frames;
   1033     frames.push_back(data1);
   1034     session_.OnStreamFrames(frames);
   1035     EXPECT_EQ(1u, session_.GetNumOpenStreams());
   1036     session_.CloseStream(i);
   1037   }
   1038 
   1039   // Called after any new data is received by the session, and triggers the call
   1040   // to close the connection.
   1041   session_.PostProcessAfterData();
   1042 }
   1043 
   1044 }  // namespace
   1045 }  // namespace test
   1046 }  // namespace net
   1047