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 |