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