| 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/reliable_quic_stream.h" | 5 #include "net/quic/reliable_quic_stream.h" |
| 6 | 6 |
| 7 #include "net/quic/quic_connection.h" | 7 #include "net/quic/quic_connection.h" |
| 8 #include "net/quic/quic_spdy_compressor.h" | 8 #include "net/quic/quic_spdy_compressor.h" |
| 9 #include "net/quic/quic_spdy_decompressor.h" | 9 #include "net/quic/quic_spdy_decompressor.h" |
| 10 #include "net/quic/quic_utils.h" | 10 #include "net/quic/quic_utils.h" |
| 11 #include "net/quic/spdy_utils.h" | 11 #include "net/quic/spdy_utils.h" |
| 12 #include "net/quic/test_tools/quic_session_peer.h" | |
| 13 #include "net/quic/test_tools/quic_test_utils.h" | 12 #include "net/quic/test_tools/quic_test_utils.h" |
| 14 #include "testing/gmock/include/gmock/gmock.h" | 13 #include "testing/gmock/include/gmock/gmock.h" |
| 15 | 14 |
| 16 using base::StringPiece; | 15 using base::StringPiece; |
| 17 using std::min; | 16 using std::min; |
| 18 using testing::_; | 17 using testing::_; |
| 19 using testing::InSequence; | 18 using testing::InSequence; |
| 20 using testing::Return; | 19 using testing::Return; |
| 21 using testing::SaveArg; | 20 using testing::SaveArg; |
| 22 using testing::StrEq; | 21 using testing::StrEq; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 connection_ = new testing::StrictMock<MockConnection>( | 71 connection_ = new testing::StrictMock<MockConnection>( |
| 73 kGuid, IPEndPoint(), kIsServer); | 72 kGuid, IPEndPoint(), kIsServer); |
| 74 session_.reset(new testing::StrictMock<MockSession>( | 73 session_.reset(new testing::StrictMock<MockSession>( |
| 75 connection_, kIsServer)); | 74 connection_, kIsServer)); |
| 76 stream_.reset(new TestStream(kStreamId, session_.get(), | 75 stream_.reset(new TestStream(kStreamId, session_.get(), |
| 77 stream_should_process_data)); | 76 stream_should_process_data)); |
| 78 stream2_.reset(new TestStream(kStreamId + 2, session_.get(), | 77 stream2_.reset(new TestStream(kStreamId + 2, session_.get(), |
| 79 stream_should_process_data)); | 78 stream_should_process_data)); |
| 80 compressor_.reset(new QuicSpdyCompressor()); | 79 compressor_.reset(new QuicSpdyCompressor()); |
| 81 decompressor_.reset(new QuicSpdyDecompressor); | 80 decompressor_.reset(new QuicSpdyDecompressor); |
| 82 write_blocked_list_ = | |
| 83 QuicSessionPeer::GetWriteblockedStreams(session_.get()); | |
| 84 } | 81 } |
| 85 | 82 |
| 86 protected: | 83 protected: |
| 87 MockConnection* connection_; | 84 MockConnection* connection_; |
| 88 scoped_ptr<MockSession> session_; | 85 scoped_ptr<MockSession> session_; |
| 89 scoped_ptr<TestStream> stream_; | 86 scoped_ptr<TestStream> stream_; |
| 90 scoped_ptr<TestStream> stream2_; | 87 scoped_ptr<TestStream> stream2_; |
| 91 scoped_ptr<QuicSpdyCompressor> compressor_; | 88 scoped_ptr<QuicSpdyCompressor> compressor_; |
| 92 scoped_ptr<QuicSpdyDecompressor> decompressor_; | 89 scoped_ptr<QuicSpdyDecompressor> decompressor_; |
| 93 SpdyHeaderBlock headers_; | 90 SpdyHeaderBlock headers_; |
| 94 BlockedList<QuicStreamId>* write_blocked_list_; | |
| 95 }; | 91 }; |
| 96 | 92 |
| 97 TEST_F(ReliableQuicStreamTest, WriteAllData) { | 93 TEST_F(ReliableQuicStreamTest, WriteAllData) { |
| 98 Initialize(kShouldProcessData); | 94 Initialize(kShouldProcessData); |
| 99 | 95 |
| 100 connection_->options()->max_packet_length = | 96 connection_->options()->max_packet_length = |
| 101 1 + QuicPacketCreator::StreamFramePacketOverhead( | 97 1 + QuicPacketCreator::StreamFramePacketOverhead( |
| 102 1, PACKET_8BYTE_GUID, !kIncludeVersion, | 98 1, PACKET_8BYTE_GUID, !kIncludeVersion, NOT_IN_FEC_GROUP); |
| 103 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 104 // TODO(rch): figure out how to get StrEq working here. | 99 // TODO(rch): figure out how to get StrEq working here. |
| 105 //EXPECT_CALL(*session_, WriteData(kStreamId, StrEq(kData1), _, _)).WillOnce( | 100 //EXPECT_CALL(*session_, WriteData(kStreamId, StrEq(kData1), _, _)).WillOnce( |
| 106 EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce( | 101 EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce( |
| 107 Return(QuicConsumedData(kDataLen, true))); | 102 Return(QuicConsumedData(kDataLen, true))); |
| 108 EXPECT_EQ(kDataLen, stream_->WriteData(kData1, false).bytes_consumed); | 103 EXPECT_EQ(kDataLen, stream_->WriteData(kData1, false).bytes_consumed); |
| 109 EXPECT_TRUE(write_blocked_list_->IsEmpty()); | |
| 110 } | |
| 111 | |
| 112 #if GTEST_HAS_DEATH_TEST && !defined(NDEBUG) | |
| 113 TEST_F(ReliableQuicStreamTest, NoBlockingIfNoDataOrFin) { | |
| 114 Initialize(kShouldProcessData); | |
| 115 | |
| 116 // Write no data and no fin. If we consume nothing we should not be write | |
| 117 // blocked. | |
| 118 EXPECT_DEBUG_DEATH({ | |
| 119 EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce( | |
| 120 Return(QuicConsumedData(0, false))); | |
| 121 stream_->WriteData(StringPiece(), false); | |
| 122 EXPECT_TRUE(write_blocked_list_->IsEmpty()); | |
| 123 }, ""); | |
| 124 } | |
| 125 #endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG) | |
| 126 | |
| 127 TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) { | |
| 128 Initialize(kShouldProcessData); | |
| 129 | |
| 130 // Write some data and no fin. If we consume some but not all of the data, | |
| 131 // we should be write blocked a not all the data was consumed. | |
| 132 EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce( | |
| 133 Return(QuicConsumedData(1, false))); | |
| 134 stream_->WriteData(StringPiece(kData1, 2), false); | |
| 135 ASSERT_EQ(1, write_blocked_list_->NumObjects()); | |
| 136 } | |
| 137 | |
| 138 | |
| 139 TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) { | |
| 140 Initialize(kShouldProcessData); | |
| 141 | |
| 142 // Write some data and no fin. If we consume all the data but not the fin, | |
| 143 // we should be write blocked because the fin was not consumed. | |
| 144 // (This should never actually happen as the fin should be sent out with the | |
| 145 // last data) | |
| 146 EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce( | |
| 147 Return(QuicConsumedData(2, false))); | |
| 148 stream_->WriteData(StringPiece(kData1, 2), true); | |
| 149 ASSERT_EQ(1, write_blocked_list_->NumObjects()); | |
| 150 } | |
| 151 | |
| 152 TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) { | |
| 153 Initialize(kShouldProcessData); | |
| 154 | |
| 155 // Write no data and a fin. If we consume nothing we should be write blocked, | |
| 156 // as the fin was not consumed. | |
| 157 EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce( | |
| 158 Return(QuicConsumedData(0, false))); | |
| 159 stream_->WriteData(StringPiece(), true); | |
| 160 ASSERT_EQ(1, write_blocked_list_->NumObjects()); | |
| 161 } | 104 } |
| 162 | 105 |
| 163 TEST_F(ReliableQuicStreamTest, WriteData) { | 106 TEST_F(ReliableQuicStreamTest, WriteData) { |
| 164 Initialize(kShouldProcessData); | 107 Initialize(kShouldProcessData); |
| 165 | 108 |
| 166 EXPECT_TRUE(write_blocked_list_->IsEmpty()); | |
| 167 connection_->options()->max_packet_length = | 109 connection_->options()->max_packet_length = |
| 168 1 + QuicPacketCreator::StreamFramePacketOverhead( | 110 1 + QuicPacketCreator::StreamFramePacketOverhead( |
| 169 1, PACKET_8BYTE_GUID, !kIncludeVersion, | 111 1, PACKET_8BYTE_GUID, !kIncludeVersion, NOT_IN_FEC_GROUP); |
| 170 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | |
| 171 // TODO(rch): figure out how to get StrEq working here. | 112 // TODO(rch): figure out how to get StrEq working here. |
| 172 //EXPECT_CALL(*session_, WriteData(_, StrEq(kData1), _, _)).WillOnce( | 113 //EXPECT_CALL(*session_, WriteData(_, StrEq(kData1), _, _)).WillOnce( |
| 173 EXPECT_CALL(*session_, WriteData(_, _, _, _)).WillOnce( | 114 EXPECT_CALL(*session_, WriteData(_, _, _, _)).WillOnce( |
| 174 Return(QuicConsumedData(kDataLen - 1, false))); | 115 Return(QuicConsumedData(kDataLen - 1, false))); |
| 175 // The return will be kDataLen, because the last byte gets buffered. | 116 // The return will be kDataLen, because the last byte gets buffered. |
| 176 EXPECT_EQ(kDataLen, stream_->WriteData(kData1, false).bytes_consumed); | 117 EXPECT_EQ(kDataLen, stream_->WriteData(kData1, false).bytes_consumed); |
| 177 EXPECT_FALSE(write_blocked_list_->IsEmpty()); | |
| 178 | 118 |
| 179 // Queue a bytes_consumed write. | 119 // Queue a bytes_consumed write. |
| 180 EXPECT_EQ(kDataLen, stream_->WriteData(kData2, false).bytes_consumed); | 120 EXPECT_EQ(kDataLen, stream_->WriteData(kData2, false).bytes_consumed); |
| 181 | 121 |
| 182 // Make sure we get the tail of the first write followed by the bytes_consumed | 122 // Make sure we get the tail of the first write followed by the bytes_consumed |
| 183 InSequence s; | 123 InSequence s; |
| 184 //EXPECT_CALL(*session_, WriteData(_, StrEq(&kData1[kDataLen - 1]), _, _)). | 124 //EXPECT_CALL(*session_, WriteData(_, StrEq(&kData1[kDataLen - 1]), _, _)). |
| 185 EXPECT_CALL(*session_, WriteData(_, _, _, _)). | 125 EXPECT_CALL(*session_, WriteData(_, _, _, _)). |
| 186 WillOnce(Return(QuicConsumedData(1, false))); | 126 WillOnce(Return(QuicConsumedData(1, false))); |
| 187 //EXPECT_CALL(*session_, WriteData(_, StrEq(kData2), _, _)). | 127 //EXPECT_CALL(*session_, WriteData(_, StrEq(kData2), _, _)). |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_HEADER_ID)) | 329 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_HEADER_ID)) |
| 390 .Times(0); | 330 .Times(0); |
| 391 QuicStreamFrame frame2(stream_->id(), false, compressed_headers.length(), | 331 QuicStreamFrame frame2(stream_->id(), false, compressed_headers.length(), |
| 392 "body data"); | 332 "body data"); |
| 393 stream_->OnStreamFrame(frame2); | 333 stream_->OnStreamFrame(frame2); |
| 394 } | 334 } |
| 395 | 335 |
| 396 } // namespace | 336 } // namespace |
| 397 } // namespace test | 337 } // namespace test |
| 398 } // namespace net | 338 } // namespace net |
| OLD | NEW |