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 |