| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/core/quic_spdy_stream.h" | 5 #include "net/quic/core/quic_spdy_stream.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "net/quic/core/quic_connection.h" | 10 #include "net/quic/core/quic_connection.h" |
| 11 #include "net/quic/core/quic_utils.h" | 11 #include "net/quic/core/quic_utils.h" |
| 12 #include "net/quic/core/quic_write_blocked_list.h" | 12 #include "net/quic/core/quic_write_blocked_list.h" |
| 13 #include "net/quic/core/spdy_utils.h" | 13 #include "net/quic/core/spdy_utils.h" |
| 14 #include "net/quic/platform/api/quic_map_util.h" |
| 14 #include "net/quic/platform/api/quic_ptr_util.h" | 15 #include "net/quic/platform/api/quic_ptr_util.h" |
| 15 #include "net/quic/platform/api/quic_string_piece.h" | 16 #include "net/quic/platform/api/quic_string_piece.h" |
| 16 #include "net/quic/platform/api/quic_test.h" | 17 #include "net/quic/platform/api/quic_test.h" |
| 17 #include "net/quic/platform/api/quic_text_utils.h" | 18 #include "net/quic/platform/api/quic_text_utils.h" |
| 18 #include "net/quic/test_tools/quic_flow_controller_peer.h" | 19 #include "net/quic/test_tools/quic_flow_controller_peer.h" |
| 20 #include "net/quic/test_tools/quic_session_peer.h" |
| 19 #include "net/quic/test_tools/quic_spdy_session_peer.h" | 21 #include "net/quic/test_tools/quic_spdy_session_peer.h" |
| 20 #include "net/quic/test_tools/quic_stream_peer.h" | 22 #include "net/quic/test_tools/quic_stream_peer.h" |
| 21 #include "net/quic/test_tools/quic_test_utils.h" | 23 #include "net/quic/test_tools/quic_test_utils.h" |
| 22 | 24 |
| 23 using std::string; | 25 using std::string; |
| 24 using testing::AnyNumber; | 26 using testing::AnyNumber; |
| 25 using testing::Invoke; | 27 using testing::Invoke; |
| 26 using testing::Return; | 28 using testing::Return; |
| 27 using testing::StrictMock; | 29 using testing::StrictMock; |
| 28 using testing::_; | 30 using testing::_; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 48 char buffer[2048]; | 50 char buffer[2048]; |
| 49 struct iovec vec; | 51 struct iovec vec; |
| 50 vec.iov_base = buffer; | 52 vec.iov_base = buffer; |
| 51 vec.iov_len = arraysize(buffer); | 53 vec.iov_len = arraysize(buffer); |
| 52 size_t bytes_read = Readv(&vec, 1); | 54 size_t bytes_read = Readv(&vec, 1); |
| 53 data_ += string(buffer, bytes_read); | 55 data_ += string(buffer, bytes_read); |
| 54 } | 56 } |
| 55 | 57 |
| 56 using QuicStream::WriteOrBufferData; | 58 using QuicStream::WriteOrBufferData; |
| 57 using QuicStream::CloseWriteSide; | 59 using QuicStream::CloseWriteSide; |
| 60 using QuicSpdyStream::set_ack_listener; |
| 58 | 61 |
| 59 const string& data() const { return data_; } | 62 const string& data() const { return data_; } |
| 60 | 63 |
| 61 private: | 64 private: |
| 62 bool should_process_data_; | 65 bool should_process_data_; |
| 63 string data_; | 66 string data_; |
| 64 }; | 67 }; |
| 65 | 68 |
| 66 class QuicSpdyStreamTest : public QuicTestWithParam<QuicVersion> { | 69 class QuicSpdyStreamTest : public QuicTestWithParam<QuicVersion> { |
| 67 public: | 70 public: |
| (...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 956 EXPECT_CALL(*session_, WriteHeadersMock(_, _, _, _, _)); | 959 EXPECT_CALL(*session_, WriteHeadersMock(_, _, _, _, _)); |
| 957 stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr); | 960 stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr); |
| 958 EXPECT_TRUE(stream_->fin_sent()); | 961 EXPECT_TRUE(stream_->fin_sent()); |
| 959 | 962 |
| 960 // Writing Trailers should fail, as the FIN has already been sent. | 963 // Writing Trailers should fail, as the FIN has already been sent. |
| 961 // populated with the number of body bytes written. | 964 // populated with the number of body bytes written. |
| 962 EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr), | 965 EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr), |
| 963 "Trailers cannot be sent after a FIN"); | 966 "Trailers cannot be sent after a FIN"); |
| 964 } | 967 } |
| 965 | 968 |
| 969 TEST_P(QuicSpdyStreamTest, HeaderStreamNotiferCorrespondingSpdyStream) { |
| 970 Initialize(kShouldProcessData); |
| 971 if (!session_->use_stream_notifier()) { |
| 972 return; |
| 973 } |
| 974 |
| 975 EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) |
| 976 .Times(AnyNumber()) |
| 977 .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData)); |
| 978 testing::InSequence s; |
| 979 QuicReferenceCountedPointer<MockAckListener> ack_listener1( |
| 980 new MockAckListener()); |
| 981 QuicReferenceCountedPointer<MockAckListener> ack_listener2( |
| 982 new MockAckListener()); |
| 983 stream_->set_ack_listener(ack_listener1); |
| 984 stream2_->set_ack_listener(ack_listener2); |
| 985 |
| 986 session_->headers_stream()->WriteOrBufferData("Header1", false, |
| 987 ack_listener1); |
| 988 stream_->WriteOrBufferData("Test1", true, nullptr); |
| 989 |
| 990 session_->headers_stream()->WriteOrBufferData("Header2", false, |
| 991 ack_listener2); |
| 992 stream2_->WriteOrBufferData("Test2", false, nullptr); |
| 993 |
| 994 QuicStreamFrame frame1(kHeadersStreamId, false, 0, "Header1"); |
| 995 QuicStreamFrame frame2(stream_->id(), true, 0, "Test1"); |
| 996 QuicStreamFrame frame3(kHeadersStreamId, false, 7, "Header2"); |
| 997 QuicStreamFrame frame4(stream2_->id(), false, 0, "Test2"); |
| 998 |
| 999 EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(7)); |
| 1000 session_->OnStreamFrameRetransmitted(frame1); |
| 1001 |
| 1002 EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _)); |
| 1003 session_->OnStreamFrameAcked(frame1, QuicTime::Delta::Zero()); |
| 1004 EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _)); |
| 1005 session_->OnStreamFrameAcked(frame2, QuicTime::Delta::Zero()); |
| 1006 EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _)); |
| 1007 session_->OnStreamFrameAcked(frame3, QuicTime::Delta::Zero()); |
| 1008 EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _)); |
| 1009 session_->OnStreamFrameAcked(frame4, QuicTime::Delta::Zero()); |
| 1010 } |
| 1011 |
| 1012 TEST_P(QuicSpdyStreamTest, StreamBecomesZombieWithWriteThatCloses) { |
| 1013 Initialize(kShouldProcessData); |
| 1014 if (!session_->use_stream_notifier()) { |
| 1015 return; |
| 1016 } |
| 1017 |
| 1018 EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) |
| 1019 .Times(AnyNumber()) |
| 1020 .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData)); |
| 1021 QuicStreamPeer::CloseReadSide(stream_); |
| 1022 // This write causes stream to be closed. |
| 1023 stream_->WriteOrBufferData("Test1", true, nullptr); |
| 1024 // stream_ has unacked data and should become zombie. |
| 1025 EXPECT_TRUE(QuicContainsKey(QuicSessionPeer::zombie_streams(session_.get()), |
| 1026 stream_->id())); |
| 1027 EXPECT_TRUE(QuicSessionPeer::closed_streams(session_.get()).empty()); |
| 1028 } |
| 1029 |
| 966 } // namespace | 1030 } // namespace |
| 967 } // namespace test | 1031 } // namespace test |
| 968 } // namespace net | 1032 } // namespace net |
| OLD | NEW |