| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_session.h" | 5 #include "net/quic/quic_session.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/containers/hash_tables.h" | 10 #include "base/containers/hash_tables.h" |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 | 177 |
| 178 private: | 178 private: |
| 179 StrictMock<TestCryptoStream> crypto_stream_; | 179 StrictMock<TestCryptoStream> crypto_stream_; |
| 180 | 180 |
| 181 bool writev_consumes_all_data_; | 181 bool writev_consumes_all_data_; |
| 182 }; | 182 }; |
| 183 | 183 |
| 184 class QuicSessionTest : public ::testing::TestWithParam<QuicVersion> { | 184 class QuicSessionTest : public ::testing::TestWithParam<QuicVersion> { |
| 185 protected: | 185 protected: |
| 186 QuicSessionTest() | 186 QuicSessionTest() |
| 187 : connection_(new MockConnection(Perspective::IS_SERVER, | 187 : connection_( |
| 188 SupportedVersions(GetParam()))), | 188 new StrictMock<MockConnection>(Perspective::IS_SERVER, |
| 189 SupportedVersions(GetParam()))), |
| 189 session_(connection_) { | 190 session_(connection_) { |
| 190 session_.config()->SetInitialStreamFlowControlWindowToSend( | 191 session_.config()->SetInitialStreamFlowControlWindowToSend( |
| 191 kInitialStreamFlowControlWindowForTest); | 192 kInitialStreamFlowControlWindowForTest); |
| 192 session_.config()->SetInitialSessionFlowControlWindowToSend( | 193 session_.config()->SetInitialSessionFlowControlWindowToSend( |
| 193 kInitialSessionFlowControlWindowForTest); | 194 kInitialSessionFlowControlWindowForTest); |
| 194 headers_[":host"] = "www.google.com"; | 195 headers_[":host"] = "www.google.com"; |
| 195 headers_[":path"] = "/index.hml"; | 196 headers_[":path"] = "/index.hml"; |
| 196 headers_[":scheme"] = "http"; | 197 headers_[":scheme"] = "http"; |
| 197 headers_["cookie"] = | 198 headers_["cookie"] = |
| 198 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " | 199 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " |
| (...skipping 26 matching lines...) Expand all Loading... |
| 225 for (int i = kCryptoStreamId; i < 100; i++) { | 226 for (int i = kCryptoStreamId; i < 100; i++) { |
| 226 if (!ContainsKey(closed_streams_, i)) { | 227 if (!ContainsKey(closed_streams_, i)) { |
| 227 EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i; | 228 EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i; |
| 228 } else { | 229 } else { |
| 229 EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i; | 230 EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i; |
| 230 } | 231 } |
| 231 } | 232 } |
| 232 } | 233 } |
| 233 | 234 |
| 234 void CloseStream(QuicStreamId id) { | 235 void CloseStream(QuicStreamId id) { |
| 236 EXPECT_CALL(*connection_, SendRstStream(id, _, _)); |
| 235 session_.CloseStream(id); | 237 session_.CloseStream(id); |
| 236 closed_streams_.insert(id); | 238 closed_streams_.insert(id); |
| 237 } | 239 } |
| 238 | 240 |
| 239 QuicVersion version() const { return connection_->version(); } | 241 QuicVersion version() const { return connection_->version(); } |
| 240 | 242 |
| 241 MockConnection* connection_; | 243 StrictMock<MockConnection>* connection_; |
| 242 TestSession session_; | 244 TestSession session_; |
| 243 set<QuicStreamId> closed_streams_; | 245 set<QuicStreamId> closed_streams_; |
| 244 SpdyHeaderBlock headers_; | 246 SpdyHeaderBlock headers_; |
| 245 }; | 247 }; |
| 246 | 248 |
| 247 INSTANTIATE_TEST_CASE_P(Tests, QuicSessionTest, | 249 INSTANTIATE_TEST_CASE_P(Tests, QuicSessionTest, |
| 248 ::testing::ValuesIn(QuicSupportedVersions())); | 250 ::testing::ValuesIn(QuicSupportedVersions())); |
| 249 | 251 |
| 250 TEST_P(QuicSessionTest, PeerAddress) { | 252 TEST_P(QuicSessionTest, PeerAddress) { |
| 251 EXPECT_EQ(IPEndPoint(Loopback4(), kTestPort), session_.peer_address()); | 253 EXPECT_EQ(IPEndPoint(Loopback4(), kTestPort), session_.peer_address()); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 }; | 333 }; |
| 332 EXPECT_CALL(*connection_, SendConnectionCloseWithDetails( | 334 EXPECT_CALL(*connection_, SendConnectionCloseWithDetails( |
| 333 QUIC_INVALID_HEADERS_STREAM_DATA, | 335 QUIC_INVALID_HEADERS_STREAM_DATA, |
| 334 "SPDY framing error: DECOMPRESS_FAILURE")); | 336 "SPDY framing error: DECOMPRESS_FAILURE")); |
| 335 stream->ProcessRawData(reinterpret_cast<const char*>(data), | 337 stream->ProcessRawData(reinterpret_cast<const char*>(data), |
| 336 arraysize(data)); | 338 arraysize(data)); |
| 337 } | 339 } |
| 338 | 340 |
| 339 TEST_P(QuicSessionTest, DebugDFatalIfMarkingClosedStreamWriteBlocked) { | 341 TEST_P(QuicSessionTest, DebugDFatalIfMarkingClosedStreamWriteBlocked) { |
| 340 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 342 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
| 343 QuicStreamId kClosedStreamId = stream2->id(); |
| 341 // Close the stream. | 344 // Close the stream. |
| 345 EXPECT_CALL(*connection_, SendRstStream(kClosedStreamId, _, _)); |
| 342 stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD); | 346 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 EXPECT_DEBUG_DFATAL( |
| 347 session_.MarkWriteBlocked(kClosedStreamId, kSomeMiddlePriority), | 348 session_.MarkWriteBlocked(kClosedStreamId, kSomeMiddlePriority), |
| 348 "Marking unknown stream 2 blocked."); | 349 "Marking unknown stream 2 blocked."); |
| 349 */ | |
| 350 } | 350 } |
| 351 | 351 |
| 352 TEST_P(QuicSessionTest, DebugDFatalIfMarkWriteBlockedCalledWithWrongPriority) { | 352 TEST_P(QuicSessionTest, DebugDFatalIfMarkWriteBlockedCalledWithWrongPriority) { |
| 353 const QuicPriority kDifferentPriority = 0; | 353 const QuicPriority kDifferentPriority = 0; |
| 354 | 354 |
| 355 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 355 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
| 356 EXPECT_NE(kDifferentPriority, stream2->EffectivePriority()); | 356 EXPECT_NE(kDifferentPriority, stream2->EffectivePriority()); |
| 357 // TODO(rtenneti): enable when chromium supports EXPECT_DEBUG_DFATAL. | |
| 358 /* | |
| 359 EXPECT_DEBUG_DFATAL( | 357 EXPECT_DEBUG_DFATAL( |
| 360 session_.MarkWriteBlocked(stream2->id(), kDifferentPriority), | 358 session_.MarkWriteBlocked(stream2->id(), kDifferentPriority), |
| 361 "Priorities do not match. Got: 0 Expected: 3"); | 359 "Priorities do not match. Got: 0 Expected: 3"); |
| 362 */ | |
| 363 } | 360 } |
| 364 | 361 |
| 365 TEST_P(QuicSessionTest, OnCanWrite) { | 362 TEST_P(QuicSessionTest, OnCanWrite) { |
| 366 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 363 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
| 367 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 364 TestStream* stream4 = session_.CreateOutgoingDataStream(); |
| 368 TestStream* stream6 = session_.CreateOutgoingDataStream(); | 365 TestStream* stream6 = session_.CreateOutgoingDataStream(); |
| 369 | 366 |
| 370 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); | 367 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); |
| 371 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); | 368 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); |
| 372 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); | 369 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 } | 584 } |
| 588 | 585 |
| 589 TEST_P(QuicSessionTest, RstStreamBeforeHeadersDecompressed) { | 586 TEST_P(QuicSessionTest, RstStreamBeforeHeadersDecompressed) { |
| 590 // Send two bytes of payload. | 587 // Send two bytes of payload. |
| 591 QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT")); | 588 QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT")); |
| 592 vector<QuicStreamFrame> frames; | 589 vector<QuicStreamFrame> frames; |
| 593 frames.push_back(data1); | 590 frames.push_back(data1); |
| 594 session_.OnStreamFrames(frames); | 591 session_.OnStreamFrames(frames); |
| 595 EXPECT_EQ(1u, session_.GetNumOpenStreams()); | 592 EXPECT_EQ(1u, session_.GetNumOpenStreams()); |
| 596 | 593 |
| 594 EXPECT_CALL(*connection_, SendRstStream(kClientDataStreamId1, _, _)); |
| 597 QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0); | 595 QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0); |
| 598 session_.OnRstStream(rst1); | 596 session_.OnRstStream(rst1); |
| 599 EXPECT_EQ(0u, session_.GetNumOpenStreams()); | 597 EXPECT_EQ(0u, session_.GetNumOpenStreams()); |
| 600 // Connection should remain alive. | 598 // Connection should remain alive. |
| 601 EXPECT_TRUE(connection_->connected()); | 599 EXPECT_TRUE(connection_->connected()); |
| 602 } | 600 } |
| 603 | 601 |
| 604 TEST_P(QuicSessionTest, MultipleRstStreamsCauseSingleConnectionClose) { | 602 TEST_P(QuicSessionTest, MultipleRstStreamsCauseSingleConnectionClose) { |
| 605 // If multiple invalid reset stream frames arrive in a single packet, this | 603 // If multiple invalid reset stream frames arrive in a single packet, this |
| 606 // should trigger a connection close. However there is no need to send | 604 // should trigger a connection close. However there is no need to send |
| (...skipping 28 matching lines...) Expand all Loading... |
| 635 // Ensure that Writev consumes all the data it is given (simulate no socket | 633 // Ensure that Writev consumes all the data it is given (simulate no socket |
| 636 // blocking). | 634 // blocking). |
| 637 session_.set_writev_consumes_all_data(true); | 635 session_.set_writev_consumes_all_data(true); |
| 638 | 636 |
| 639 // Create a stream, and send enough data to make it flow control blocked. | 637 // Create a stream, and send enough data to make it flow control blocked. |
| 640 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 638 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
| 641 string body(kMinimumFlowControlSendWindow, '.'); | 639 string body(kMinimumFlowControlSendWindow, '.'); |
| 642 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); | 640 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); |
| 643 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 641 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 644 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 642 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 643 EXPECT_CALL(*connection_, SendBlocked(stream2->id())); |
| 644 EXPECT_CALL(*connection_, SendBlocked(0)); |
| 645 stream2->SendBody(body, false); | 645 stream2->SendBody(body, false); |
| 646 EXPECT_TRUE(stream2->flow_controller()->IsBlocked()); | 646 EXPECT_TRUE(stream2->flow_controller()->IsBlocked()); |
| 647 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); | 647 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); |
| 648 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); | 648 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); |
| 649 | 649 |
| 650 // The handshake message will call OnCanWrite, so the stream can resume | 650 // The handshake message will call OnCanWrite, so the stream can resume |
| 651 // writing. | 651 // writing. |
| 652 EXPECT_CALL(*stream2, OnCanWrite()); | 652 EXPECT_CALL(*stream2, OnCanWrite()); |
| 653 // Now complete the crypto handshake, resulting in an increased flow control | 653 // Now complete the crypto handshake, resulting in an increased flow control |
| 654 // send window. | 654 // send window. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 668 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); | 668 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); |
| 669 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); | 669 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
| 670 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 670 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 671 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 671 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 672 QuicHeadersStream* headers_stream = | 672 QuicHeadersStream* headers_stream = |
| 673 QuicSessionPeer::GetHeadersStream(&session_); | 673 QuicSessionPeer::GetHeadersStream(&session_); |
| 674 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); | 674 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
| 675 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 675 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 676 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 676 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 677 // Write until the crypto stream is flow control blocked. | 677 // Write until the crypto stream is flow control blocked. |
| 678 EXPECT_CALL(*connection_, SendBlocked(kCryptoStreamId)); |
| 678 int i = 0; | 679 int i = 0; |
| 679 while (!crypto_stream->flow_controller()->IsBlocked() && i < 1000) { | 680 while (!crypto_stream->flow_controller()->IsBlocked() && i < 1000) { |
| 680 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 681 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 681 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 682 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 682 QuicConfig config; | 683 QuicConfig config; |
| 683 CryptoHandshakeMessage crypto_message; | 684 CryptoHandshakeMessage crypto_message; |
| 684 config.ToHandshakeMessage(&crypto_message); | 685 config.ToHandshakeMessage(&crypto_message); |
| 685 crypto_stream->SendHandshakeMessage(crypto_message); | 686 crypto_stream->SendHandshakeMessage(crypto_message); |
| 686 ++i; | 687 ++i; |
| 687 } | 688 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 714 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); | 715 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
| 715 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 716 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 716 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 717 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 717 QuicHeadersStream* headers_stream = | 718 QuicHeadersStream* headers_stream = |
| 718 QuicSessionPeer::GetHeadersStream(&session_); | 719 QuicSessionPeer::GetHeadersStream(&session_); |
| 719 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); | 720 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
| 720 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 721 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 721 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 722 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 722 QuicStreamId stream_id = 5; | 723 QuicStreamId stream_id = 5; |
| 723 // Write until the header stream is flow control blocked. | 724 // Write until the header stream is flow control blocked. |
| 725 EXPECT_CALL(*connection_, SendBlocked(kHeadersStreamId)); |
| 724 SpdyHeaderBlock headers; | 726 SpdyHeaderBlock headers; |
| 725 while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) { | 727 while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) { |
| 726 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 728 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 727 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 729 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 728 headers["header"] = base::Uint64ToString(base::RandUint64()) + | 730 headers["header"] = base::Uint64ToString(base::RandUint64()) + |
| 729 base::Uint64ToString(base::RandUint64()) + | 731 base::Uint64ToString(base::RandUint64()) + |
| 730 base::Uint64ToString(base::RandUint64()); | 732 base::Uint64ToString(base::RandUint64()); |
| 731 headers_stream->WriteHeaders(stream_id, headers, true, 0, nullptr); | 733 headers_stream->WriteHeaders(stream_id, headers, true, 0, nullptr); |
| 732 stream_id += 2; | 734 stream_id += 2; |
| 733 } | 735 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 764 const QuicStreamOffset kByteOffset = | 766 const QuicStreamOffset kByteOffset = |
| 765 1 + kInitialSessionFlowControlWindowForTest / 2; | 767 1 + kInitialSessionFlowControlWindowForTest / 2; |
| 766 | 768 |
| 767 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. | 769 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. |
| 768 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); | 770 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); |
| 769 // We do expect a connection level WINDOW_UPDATE when the stream is reset. | 771 // We do expect a connection level WINDOW_UPDATE when the stream is reset. |
| 770 EXPECT_CALL(*connection_, | 772 EXPECT_CALL(*connection_, |
| 771 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + | 773 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + |
| 772 kByteOffset)).Times(1); | 774 kByteOffset)).Times(1); |
| 773 | 775 |
| 776 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); |
| 774 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 777 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
| 775 kByteOffset); | 778 kByteOffset); |
| 776 session_.OnRstStream(rst_frame); | 779 session_.OnRstStream(rst_frame); |
| 777 session_.PostProcessAfterData(); | 780 session_.PostProcessAfterData(); |
| 778 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); | 781 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); |
| 779 } | 782 } |
| 780 | 783 |
| 781 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAndLocalReset) { | 784 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAndLocalReset) { |
| 782 // Test the situation where we receive a FIN on a stream, and before we fully | 785 // Test the situation where we receive a FIN on a stream, and before we fully |
| 783 // consume all the data from the sequencer buffer we locally RST the stream. | 786 // consume all the data from the sequencer buffer we locally RST the stream. |
| 784 // The bytes between highest consumed byte, and the final byte offset that we | 787 // The bytes between highest consumed byte, and the final byte offset that we |
| 785 // determined when the FIN arrived, should be marked as consumed at the | 788 // determined when the FIN arrived, should be marked as consumed at the |
| 786 // connection level flow controller when the stream is reset. | 789 // connection level flow controller when the stream is reset. |
| 787 TestStream* stream = session_.CreateOutgoingDataStream(); | 790 TestStream* stream = session_.CreateOutgoingDataStream(); |
| 788 | 791 |
| 789 const QuicStreamOffset kByteOffset = | 792 const QuicStreamOffset kByteOffset = |
| 790 1 + kInitialSessionFlowControlWindowForTest / 2; | 793 kInitialSessionFlowControlWindowForTest / 2; |
| 791 QuicStreamFrame frame(stream->id(), true, kByteOffset, IOVector()); | 794 QuicStreamFrame frame(stream->id(), true, kByteOffset, IOVector()); |
| 792 vector<QuicStreamFrame> frames; | 795 vector<QuicStreamFrame> frames; |
| 793 frames.push_back(frame); | 796 frames.push_back(frame); |
| 794 session_.OnStreamFrames(frames); | 797 session_.OnStreamFrames(frames); |
| 795 session_.PostProcessAfterData(); | 798 session_.PostProcessAfterData(); |
| 799 EXPECT_TRUE(connection_->connected()); |
| 796 | 800 |
| 797 EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed()); | 801 EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed()); |
| 798 EXPECT_EQ(kByteOffset, | 802 EXPECT_EQ(kByteOffset, |
| 799 stream->flow_controller()->highest_received_byte_offset()); | 803 stream->flow_controller()->highest_received_byte_offset()); |
| 800 | 804 |
| 801 // Reset stream locally. | 805 // Reset stream locally. |
| 806 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); |
| 802 stream->Reset(QUIC_STREAM_CANCELLED); | 807 stream->Reset(QUIC_STREAM_CANCELLED); |
| 803 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); | 808 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); |
| 804 } | 809 } |
| 805 | 810 |
| 806 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAfterRst) { | 811 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAfterRst) { |
| 807 // Test that when we RST the stream (and tear down stream state), and then | 812 // Test that when we RST the stream (and tear down stream state), and then |
| 808 // receive a FIN from the peer, we correctly adjust our connection level flow | 813 // receive a FIN from the peer, we correctly adjust our connection level flow |
| 809 // control receive window. | 814 // control receive window. |
| 810 | 815 |
| 811 // Connection starts with some non-zero highest received byte offset, | 816 // Connection starts with some non-zero highest received byte offset, |
| 812 // due to other active streams. | 817 // due to other active streams. |
| 813 const uint64 kInitialConnectionBytesConsumed = 567; | 818 const uint64 kInitialConnectionBytesConsumed = 567; |
| 814 const uint64 kInitialConnectionHighestReceivedOffset = 1234; | 819 const uint64 kInitialConnectionHighestReceivedOffset = 1234; |
| 815 EXPECT_LT(kInitialConnectionBytesConsumed, | 820 EXPECT_LT(kInitialConnectionBytesConsumed, |
| 816 kInitialConnectionHighestReceivedOffset); | 821 kInitialConnectionHighestReceivedOffset); |
| 817 session_.flow_controller()->UpdateHighestReceivedOffset( | 822 session_.flow_controller()->UpdateHighestReceivedOffset( |
| 818 kInitialConnectionHighestReceivedOffset); | 823 kInitialConnectionHighestReceivedOffset); |
| 819 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); | 824 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); |
| 820 | 825 |
| 821 // Reset our stream: this results in the stream being closed locally. | 826 // Reset our stream: this results in the stream being closed locally. |
| 822 TestStream* stream = session_.CreateOutgoingDataStream(); | 827 TestStream* stream = session_.CreateOutgoingDataStream(); |
| 828 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); |
| 823 stream->Reset(QUIC_STREAM_CANCELLED); | 829 stream->Reset(QUIC_STREAM_CANCELLED); |
| 824 | 830 |
| 825 // Now receive a response from the peer with a FIN. We should handle this by | 831 // Now receive a response from the peer with a FIN. We should handle this by |
| 826 // adjusting the connection level flow control receive window to take into | 832 // adjusting the connection level flow control receive window to take into |
| 827 // account the total number of bytes sent by the peer. | 833 // account the total number of bytes sent by the peer. |
| 828 const QuicStreamOffset kByteOffset = 5678; | 834 const QuicStreamOffset kByteOffset = 5678; |
| 829 string body = "hello"; | 835 string body = "hello"; |
| 830 IOVector data = MakeIOVector(body); | 836 IOVector data = MakeIOVector(body); |
| 831 QuicStreamFrame frame(stream->id(), true, kByteOffset, data); | 837 QuicStreamFrame frame(stream->id(), true, kByteOffset, data); |
| 832 vector<QuicStreamFrame> frames; | 838 vector<QuicStreamFrame> frames; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 852 const uint64 kInitialConnectionBytesConsumed = 567; | 858 const uint64 kInitialConnectionBytesConsumed = 567; |
| 853 const uint64 kInitialConnectionHighestReceivedOffset = 1234; | 859 const uint64 kInitialConnectionHighestReceivedOffset = 1234; |
| 854 EXPECT_LT(kInitialConnectionBytesConsumed, | 860 EXPECT_LT(kInitialConnectionBytesConsumed, |
| 855 kInitialConnectionHighestReceivedOffset); | 861 kInitialConnectionHighestReceivedOffset); |
| 856 session_.flow_controller()->UpdateHighestReceivedOffset( | 862 session_.flow_controller()->UpdateHighestReceivedOffset( |
| 857 kInitialConnectionHighestReceivedOffset); | 863 kInitialConnectionHighestReceivedOffset); |
| 858 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); | 864 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); |
| 859 | 865 |
| 860 // Reset our stream: this results in the stream being closed locally. | 866 // Reset our stream: this results in the stream being closed locally. |
| 861 TestStream* stream = session_.CreateOutgoingDataStream(); | 867 TestStream* stream = session_.CreateOutgoingDataStream(); |
| 868 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); |
| 862 stream->Reset(QUIC_STREAM_CANCELLED); | 869 stream->Reset(QUIC_STREAM_CANCELLED); |
| 863 | 870 |
| 864 // Now receive a RST from the peer. We should handle this by adjusting the | 871 // Now receive a RST from the peer. We should handle this by adjusting the |
| 865 // connection level flow control receive window to take into account the total | 872 // connection level flow control receive window to take into account the total |
| 866 // number of bytes sent by the peer. | 873 // number of bytes sent by the peer. |
| 867 const QuicStreamOffset kByteOffset = 5678; | 874 const QuicStreamOffset kByteOffset = 5678; |
| 868 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 875 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
| 869 kByteOffset); | 876 kByteOffset); |
| 870 session_.OnRstStream(rst_frame); | 877 session_.OnRstStream(rst_frame); |
| 871 | 878 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 902 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { | 909 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { |
| 903 // Test that if we receive a stream RST with a highest byte offset that | 910 // Test that if we receive a stream RST with a highest byte offset that |
| 904 // violates flow control, that we close the connection. | 911 // violates flow control, that we close the connection. |
| 905 const uint64 kLargeOffset = kInitialSessionFlowControlWindowForTest + 1; | 912 const uint64 kLargeOffset = kInitialSessionFlowControlWindowForTest + 1; |
| 906 EXPECT_CALL(*connection_, | 913 EXPECT_CALL(*connection_, |
| 907 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)) | 914 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)) |
| 908 .Times(2); | 915 .Times(2); |
| 909 | 916 |
| 910 // Check that stream frame + FIN results in connection close. | 917 // Check that stream frame + FIN results in connection close. |
| 911 TestStream* stream = session_.CreateOutgoingDataStream(); | 918 TestStream* stream = session_.CreateOutgoingDataStream(); |
| 919 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); |
| 912 stream->Reset(QUIC_STREAM_CANCELLED); | 920 stream->Reset(QUIC_STREAM_CANCELLED); |
| 913 QuicStreamFrame frame(stream->id(), true, kLargeOffset, IOVector()); | 921 QuicStreamFrame frame(stream->id(), true, kLargeOffset, IOVector()); |
| 914 vector<QuicStreamFrame> frames; | 922 vector<QuicStreamFrame> frames; |
| 915 frames.push_back(frame); | 923 frames.push_back(frame); |
| 916 session_.OnStreamFrames(frames); | 924 session_.OnStreamFrames(frames); |
| 917 | 925 |
| 918 // Check that RST results in connection close. | 926 // Check that RST results in connection close. |
| 919 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 927 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
| 920 kLargeOffset); | 928 kLargeOffset); |
| 921 session_.OnRstStream(rst_frame); | 929 session_.OnRstStream(rst_frame); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 // Create kMaxStreams + 1 data streams, and close them all without receiving a | 965 // Create kMaxStreams + 1 data streams, and close them all without receiving a |
| 958 // FIN or a RST from the client. | 966 // FIN or a RST from the client. |
| 959 const int kFirstStreamId = kClientDataStreamId1; | 967 const int kFirstStreamId = kClientDataStreamId1; |
| 960 const int kFinalStreamId = kClientDataStreamId1 + 2 * kMaxStreams + 1; | 968 const int kFinalStreamId = kClientDataStreamId1 + 2 * kMaxStreams + 1; |
| 961 for (int i = kFirstStreamId; i < kFinalStreamId; i += 2) { | 969 for (int i = kFirstStreamId; i < kFinalStreamId; i += 2) { |
| 962 QuicStreamFrame data1(i, false, 0, MakeIOVector("HT")); | 970 QuicStreamFrame data1(i, false, 0, MakeIOVector("HT")); |
| 963 vector<QuicStreamFrame> frames; | 971 vector<QuicStreamFrame> frames; |
| 964 frames.push_back(data1); | 972 frames.push_back(data1); |
| 965 session_.OnStreamFrames(frames); | 973 session_.OnStreamFrames(frames); |
| 966 EXPECT_EQ(1u, session_.GetNumOpenStreams()); | 974 EXPECT_EQ(1u, session_.GetNumOpenStreams()); |
| 975 EXPECT_CALL(*connection_, SendRstStream(i, _, _)); |
| 967 session_.CloseStream(i); | 976 session_.CloseStream(i); |
| 968 } | 977 } |
| 969 | 978 |
| 970 // Called after any new data is received by the session, and triggers the call | 979 // Called after any new data is received by the session, and triggers the call |
| 971 // to close the connection. | 980 // to close the connection. |
| 972 session_.PostProcessAfterData(); | 981 session_.PostProcessAfterData(); |
| 973 } | 982 } |
| 974 | 983 |
| 975 } // namespace | 984 } // namespace |
| 976 } // namespace test | 985 } // namespace test |
| 977 } // namespace net | 986 } // namespace net |
| OLD | NEW |