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_ack_notifier.h" | 7 #include "net/quic/quic_ack_notifier.h" |
8 #include "net/quic/quic_connection.h" | 8 #include "net/quic/quic_connection.h" |
9 #include "net/quic/quic_flags.h" | 9 #include "net/quic/quic_flags.h" |
10 #include "net/quic/quic_utils.h" | 10 #include "net/quic/quic_utils.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 | 36 |
37 const char kData1[] = "FooAndBar"; | 37 const char kData1[] = "FooAndBar"; |
38 const char kData2[] = "EepAndBaz"; | 38 const char kData2[] = "EepAndBaz"; |
39 const size_t kDataLen = 9; | 39 const size_t kDataLen = 9; |
40 const QuicConnectionId kStreamId = 3; | 40 const QuicConnectionId kStreamId = 3; |
41 const bool kIsServer = true; | 41 const bool kIsServer = true; |
42 const bool kShouldProcessData = true; | 42 const bool kShouldProcessData = true; |
43 | 43 |
44 class TestStream : public ReliableQuicStream { | 44 class TestStream : public ReliableQuicStream { |
45 public: | 45 public: |
46 TestStream(QuicStreamId id, | 46 TestStream(QuicStreamId id, QuicSession* session, bool should_process_data) |
47 QuicSession* session, | |
48 bool should_process_data) | |
49 : ReliableQuicStream(id, session), | 47 : ReliableQuicStream(id, session), |
50 should_process_data_(should_process_data) {} | 48 should_process_data_(should_process_data) {} |
51 | 49 |
52 virtual uint32 ProcessRawData(const char* data, uint32 data_len) OVERRIDE { | 50 virtual uint32 ProcessRawData(const char* data, uint32 data_len) OVERRIDE { |
53 EXPECT_NE(0u, data_len); | 51 EXPECT_NE(0u, data_len); |
54 DVLOG(1) << "ProcessData data_len: " << data_len; | 52 DVLOG(1) << "ProcessData data_len: " << data_len; |
55 data_ += string(data, data_len); | 53 data_ += string(data, data_len); |
56 return should_process_data_ ? data_len : 0; | 54 return should_process_data_ ? data_len : 0; |
57 } | 55 } |
58 | 56 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 void Initialize(bool stream_should_process_data) { | 110 void Initialize(bool stream_should_process_data) { |
113 connection_ = | 111 connection_ = |
114 new StrictMock<MockConnection>(kIsServer, supported_versions_); | 112 new StrictMock<MockConnection>(kIsServer, supported_versions_); |
115 session_.reset(new StrictMock<MockSession>(connection_)); | 113 session_.reset(new StrictMock<MockSession>(connection_)); |
116 | 114 |
117 // New streams rely on having the peer's flow control receive window | 115 // New streams rely on having the peer's flow control receive window |
118 // negotiated in the config. | 116 // negotiated in the config. |
119 QuicConfigPeer::SetReceivedInitialFlowControlWindow( | 117 QuicConfigPeer::SetReceivedInitialFlowControlWindow( |
120 session_->config(), initial_flow_control_window_bytes_); | 118 session_->config(), initial_flow_control_window_bytes_); |
121 | 119 |
122 stream_.reset(new TestStream(kStreamId, session_.get(), | 120 stream_.reset( |
123 stream_should_process_data)); | 121 new TestStream(kStreamId, session_.get(), stream_should_process_data)); |
124 stream2_.reset(new TestStream(kStreamId + 2, session_.get(), | 122 stream2_.reset(new TestStream( |
125 stream_should_process_data)); | 123 kStreamId + 2, session_.get(), stream_should_process_data)); |
126 write_blocked_list_ = | 124 write_blocked_list_ = |
127 QuicSessionPeer::GetWriteblockedStreams(session_.get()); | 125 QuicSessionPeer::GetWriteblockedStreams(session_.get()); |
128 } | 126 } |
129 | 127 |
130 bool fin_sent() { return ReliableQuicStreamPeer::FinSent(stream_.get()); } | 128 bool fin_sent() { return ReliableQuicStreamPeer::FinSent(stream_.get()); } |
131 bool rst_sent() { return ReliableQuicStreamPeer::RstSent(stream_.get()); } | 129 bool rst_sent() { return ReliableQuicStreamPeer::RstSent(stream_.get()); } |
132 | 130 |
133 void set_initial_flow_control_window_bytes(uint32 val) { | 131 void set_initial_flow_control_window_bytes(uint32 val) { |
134 initial_flow_control_window_bytes_ = val; | 132 initial_flow_control_window_bytes_ = val; |
135 } | 133 } |
136 | 134 |
137 protected: | 135 protected: |
138 MockConnection* connection_; | 136 MockConnection* connection_; |
139 scoped_ptr<MockSession> session_; | 137 scoped_ptr<MockSession> session_; |
140 scoped_ptr<TestStream> stream_; | 138 scoped_ptr<TestStream> stream_; |
141 scoped_ptr<TestStream> stream2_; | 139 scoped_ptr<TestStream> stream2_; |
142 SpdyHeaderBlock headers_; | 140 SpdyHeaderBlock headers_; |
143 QuicWriteBlockedList* write_blocked_list_; | 141 QuicWriteBlockedList* write_blocked_list_; |
144 uint32 initial_flow_control_window_bytes_; | 142 uint32 initial_flow_control_window_bytes_; |
145 QuicTime::Delta zero_; | 143 QuicTime::Delta zero_; |
146 QuicVersionVector supported_versions_; | 144 QuicVersionVector supported_versions_; |
147 }; | 145 }; |
148 | 146 |
149 TEST_F(ReliableQuicStreamTest, WriteAllData) { | 147 TEST_F(ReliableQuicStreamTest, WriteAllData) { |
150 Initialize(kShouldProcessData); | 148 Initialize(kShouldProcessData); |
151 | 149 |
152 connection_->options()->max_packet_length = | 150 connection_->options()->max_packet_length = |
153 1 + QuicPacketCreator::StreamFramePacketOverhead( | 151 1 + |
154 connection_->version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | 152 QuicPacketCreator::StreamFramePacketOverhead(connection_->version(), |
155 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | 153 PACKET_8BYTE_CONNECTION_ID, |
156 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 154 !kIncludeVersion, |
157 Return(QuicConsumedData(kDataLen, true))); | 155 PACKET_6BYTE_SEQUENCE_NUMBER, |
| 156 NOT_IN_FEC_GROUP); |
| 157 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
| 158 .WillOnce(Return(QuicConsumedData(kDataLen, true))); |
158 stream_->WriteOrBufferData(kData1, false, NULL); | 159 stream_->WriteOrBufferData(kData1, false, NULL); |
159 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); | 160 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); |
160 } | 161 } |
161 | 162 |
162 TEST_F(ReliableQuicStreamTest, NoBlockingIfNoDataOrFin) { | 163 TEST_F(ReliableQuicStreamTest, NoBlockingIfNoDataOrFin) { |
163 Initialize(kShouldProcessData); | 164 Initialize(kShouldProcessData); |
164 | 165 |
165 // Write no data and no fin. If we consume nothing we should not be write | 166 // Write no data and no fin. If we consume nothing we should not be write |
166 // blocked. | 167 // blocked. |
167 EXPECT_DFATAL(stream_->WriteOrBufferData(StringPiece(), false, NULL), ""); | 168 EXPECT_DFATAL(stream_->WriteOrBufferData(StringPiece(), false, NULL), ""); |
168 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); | 169 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); |
169 } | 170 } |
170 | 171 |
171 TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) { | 172 TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) { |
172 Initialize(kShouldProcessData); | 173 Initialize(kShouldProcessData); |
173 | 174 |
174 // Write some data and no fin. If we consume some but not all of the data, | 175 // Write some data and no fin. If we consume some but not all of the data, |
175 // we should be write blocked a not all the data was consumed. | 176 // we should be write blocked a not all the data was consumed. |
176 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 177 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
177 Return(QuicConsumedData(1, false))); | 178 .WillOnce(Return(QuicConsumedData(1, false))); |
178 stream_->WriteOrBufferData(StringPiece(kData1, 2), false, NULL); | 179 stream_->WriteOrBufferData(StringPiece(kData1, 2), false, NULL); |
179 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); | 180 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); |
180 } | 181 } |
181 | 182 |
182 | |
183 TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) { | 183 TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) { |
184 Initialize(kShouldProcessData); | 184 Initialize(kShouldProcessData); |
185 | 185 |
186 // Write some data and no fin. If we consume all the data but not the fin, | 186 // Write some data and no fin. If we consume all the data but not the fin, |
187 // we should be write blocked because the fin was not consumed. | 187 // we should be write blocked because the fin was not consumed. |
188 // (This should never actually happen as the fin should be sent out with the | 188 // (This should never actually happen as the fin should be sent out with the |
189 // last data) | 189 // last data) |
190 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 190 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
191 Return(QuicConsumedData(2, false))); | 191 .WillOnce(Return(QuicConsumedData(2, false))); |
192 stream_->WriteOrBufferData(StringPiece(kData1, 2), true, NULL); | 192 stream_->WriteOrBufferData(StringPiece(kData1, 2), true, NULL); |
193 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); | 193 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); |
194 } | 194 } |
195 | 195 |
196 TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) { | 196 TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) { |
197 Initialize(kShouldProcessData); | 197 Initialize(kShouldProcessData); |
198 | 198 |
199 // Write no data and a fin. If we consume nothing we should be write blocked, | 199 // Write no data and a fin. If we consume nothing we should be write blocked, |
200 // as the fin was not consumed. | 200 // as the fin was not consumed. |
201 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 201 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
202 Return(QuicConsumedData(0, false))); | 202 .WillOnce(Return(QuicConsumedData(0, false))); |
203 stream_->WriteOrBufferData(StringPiece(), true, NULL); | 203 stream_->WriteOrBufferData(StringPiece(), true, NULL); |
204 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); | 204 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); |
205 } | 205 } |
206 | 206 |
207 TEST_F(ReliableQuicStreamTest, WriteOrBufferData) { | 207 TEST_F(ReliableQuicStreamTest, WriteOrBufferData) { |
208 Initialize(kShouldProcessData); | 208 Initialize(kShouldProcessData); |
209 | 209 |
210 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); | 210 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); |
211 connection_->options()->max_packet_length = | 211 connection_->options()->max_packet_length = |
212 1 + QuicPacketCreator::StreamFramePacketOverhead( | 212 1 + |
213 connection_->version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | 213 QuicPacketCreator::StreamFramePacketOverhead(connection_->version(), |
214 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | 214 PACKET_8BYTE_CONNECTION_ID, |
215 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).WillOnce( | 215 !kIncludeVersion, |
216 Return(QuicConsumedData(kDataLen - 1, false))); | 216 PACKET_6BYTE_SEQUENCE_NUMBER, |
| 217 NOT_IN_FEC_GROUP); |
| 218 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)) |
| 219 .WillOnce(Return(QuicConsumedData(kDataLen - 1, false))); |
217 stream_->WriteOrBufferData(kData1, false, NULL); | 220 stream_->WriteOrBufferData(kData1, false, NULL); |
218 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); | 221 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); |
219 | 222 |
220 // Queue a bytes_consumed write. | 223 // Queue a bytes_consumed write. |
221 stream_->WriteOrBufferData(kData2, false, NULL); | 224 stream_->WriteOrBufferData(kData2, false, NULL); |
222 | 225 |
223 // Make sure we get the tail of the first write followed by the bytes_consumed | 226 // Make sure we get the tail of the first write followed by the bytes_consumed |
224 InSequence s; | 227 InSequence s; |
225 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)). | 228 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)) |
226 WillOnce(Return(QuicConsumedData(1, false))); | 229 .WillOnce(Return(QuicConsumedData(1, false))); |
227 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)). | 230 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)) |
228 WillOnce(Return(QuicConsumedData(kDataLen - 2, false))); | 231 .WillOnce(Return(QuicConsumedData(kDataLen - 2, false))); |
229 stream_->OnCanWrite(); | 232 stream_->OnCanWrite(); |
230 | 233 |
231 // And finally the end of the bytes_consumed. | 234 // And finally the end of the bytes_consumed. |
232 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)). | 235 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)) |
233 WillOnce(Return(QuicConsumedData(2, true))); | 236 .WillOnce(Return(QuicConsumedData(2, true))); |
234 stream_->OnCanWrite(); | 237 stream_->OnCanWrite(); |
235 } | 238 } |
236 | 239 |
237 TEST_F(ReliableQuicStreamTest, ConnectionCloseAfterStreamClose) { | 240 TEST_F(ReliableQuicStreamTest, ConnectionCloseAfterStreamClose) { |
238 Initialize(kShouldProcessData); | 241 Initialize(kShouldProcessData); |
239 | 242 |
240 stream_->CloseReadSide(); | 243 stream_->CloseReadSide(); |
241 stream_->CloseWriteSide(); | 244 stream_->CloseWriteSide(); |
242 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error()); | 245 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error()); |
243 EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error()); | 246 EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error()); |
244 stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR, false); | 247 stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR, false); |
245 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error()); | 248 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error()); |
246 EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error()); | 249 EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error()); |
247 } | 250 } |
248 | 251 |
249 TEST_F(ReliableQuicStreamTest, RstAlwaysSentIfNoFinSent) { | 252 TEST_F(ReliableQuicStreamTest, RstAlwaysSentIfNoFinSent) { |
250 // For flow control accounting, a stream must send either a FIN or a RST frame | 253 // For flow control accounting, a stream must send either a FIN or a RST frame |
251 // before termination. | 254 // before termination. |
252 // Test that if no FIN has been sent, we send a RST. | 255 // Test that if no FIN has been sent, we send a RST. |
253 | 256 |
254 Initialize(kShouldProcessData); | 257 Initialize(kShouldProcessData); |
255 EXPECT_FALSE(fin_sent()); | 258 EXPECT_FALSE(fin_sent()); |
256 EXPECT_FALSE(rst_sent()); | 259 EXPECT_FALSE(rst_sent()); |
257 | 260 |
258 // Write some data, with no FIN. | 261 // Write some data, with no FIN. |
259 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 262 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
260 Return(QuicConsumedData(1, false))); | 263 .WillOnce(Return(QuicConsumedData(1, false))); |
261 stream_->WriteOrBufferData(StringPiece(kData1, 1), false, NULL); | 264 stream_->WriteOrBufferData(StringPiece(kData1, 1), false, NULL); |
262 EXPECT_FALSE(fin_sent()); | 265 EXPECT_FALSE(fin_sent()); |
263 EXPECT_FALSE(rst_sent()); | 266 EXPECT_FALSE(rst_sent()); |
264 | 267 |
265 // Now close the stream, and expect that we send a RST. | 268 // Now close the stream, and expect that we send a RST. |
266 EXPECT_CALL(*session_, SendRstStream(_, _, _)); | 269 EXPECT_CALL(*session_, SendRstStream(_, _, _)); |
267 stream_->OnClose(); | 270 stream_->OnClose(); |
268 EXPECT_FALSE(fin_sent()); | 271 EXPECT_FALSE(fin_sent()); |
269 EXPECT_TRUE(rst_sent()); | 272 EXPECT_TRUE(rst_sent()); |
270 } | 273 } |
271 | 274 |
272 TEST_F(ReliableQuicStreamTest, RstNotSentIfFinSent) { | 275 TEST_F(ReliableQuicStreamTest, RstNotSentIfFinSent) { |
273 // For flow control accounting, a stream must send either a FIN or a RST frame | 276 // For flow control accounting, a stream must send either a FIN or a RST frame |
274 // before termination. | 277 // before termination. |
275 // Test that if a FIN has been sent, we don't also send a RST. | 278 // Test that if a FIN has been sent, we don't also send a RST. |
276 | 279 |
277 Initialize(kShouldProcessData); | 280 Initialize(kShouldProcessData); |
278 EXPECT_FALSE(fin_sent()); | 281 EXPECT_FALSE(fin_sent()); |
279 EXPECT_FALSE(rst_sent()); | 282 EXPECT_FALSE(rst_sent()); |
280 | 283 |
281 // Write some data, with FIN. | 284 // Write some data, with FIN. |
282 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 285 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
283 Return(QuicConsumedData(1, true))); | 286 .WillOnce(Return(QuicConsumedData(1, true))); |
284 stream_->WriteOrBufferData(StringPiece(kData1, 1), true, NULL); | 287 stream_->WriteOrBufferData(StringPiece(kData1, 1), true, NULL); |
285 EXPECT_TRUE(fin_sent()); | 288 EXPECT_TRUE(fin_sent()); |
286 EXPECT_FALSE(rst_sent()); | 289 EXPECT_FALSE(rst_sent()); |
287 | 290 |
288 // Now close the stream, and expect that we do not send a RST. | 291 // Now close the stream, and expect that we do not send a RST. |
289 stream_->OnClose(); | 292 stream_->OnClose(); |
290 EXPECT_TRUE(fin_sent()); | 293 EXPECT_TRUE(fin_sent()); |
291 EXPECT_FALSE(rst_sent()); | 294 EXPECT_FALSE(rst_sent()); |
292 } | 295 } |
293 | 296 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 | 393 |
391 const int kFirstWriteSize = 100; | 394 const int kFirstWriteSize = 100; |
392 const int kSecondWriteSize = 50; | 395 const int kSecondWriteSize = 50; |
393 const int kLastWriteSize = kDataSize - kFirstWriteSize - kSecondWriteSize; | 396 const int kLastWriteSize = kDataSize - kFirstWriteSize - kSecondWriteSize; |
394 | 397 |
395 // Set a large flow control send window so this doesn't interfere with test. | 398 // Set a large flow control send window so this doesn't interfere with test. |
396 stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1); | 399 stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1); |
397 | 400 |
398 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; | 401 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; |
399 | 402 |
400 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 403 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
401 WithArgs<4>(Invoke(CreateFunctor( | 404 .WillOnce(DoAll(WithArgs<4>(Invoke(CreateFunctor( |
402 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 405 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
403 Return(QuicConsumedData(kFirstWriteSize, false)))); | 406 Return(QuicConsumedData(kFirstWriteSize, false)))); |
404 stream_->WriteOrBufferData(kData, false, delegate.get()); | 407 stream_->WriteOrBufferData(kData, false, delegate.get()); |
405 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); | 408 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); |
406 | 409 |
407 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())). | 410 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())) |
408 WillOnce( | 411 .WillOnce(Return(QuicConsumedData(kSecondWriteSize, false))); |
409 Return(QuicConsumedData(kSecondWriteSize, false))); | |
410 stream_->OnCanWrite(); | 412 stream_->OnCanWrite(); |
411 | 413 |
412 // No ack expected for an empty write. | 414 // No ack expected for an empty write. |
413 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())). | 415 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())) |
414 WillOnce( | 416 .WillOnce(Return(QuicConsumedData(0, false))); |
415 Return(QuicConsumedData(0, false))); | |
416 stream_->OnCanWrite(); | 417 stream_->OnCanWrite(); |
417 | 418 |
418 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())). | 419 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())) |
419 WillOnce( | 420 .WillOnce(Return(QuicConsumedData(kLastWriteSize, false))); |
420 Return(QuicConsumedData(kLastWriteSize, false))); | |
421 stream_->OnCanWrite(); | 421 stream_->OnCanWrite(); |
422 | 422 |
423 // There were two writes, so OnAckNotification is not propagated | 423 // There were two writes, so OnAckNotification is not propagated |
424 // until the third Ack arrives. | 424 // until the third Ack arrives. |
425 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); | 425 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); |
426 proxy_delegate->OnAckNotification(10, 20, 30, 40, zero_); | 426 proxy_delegate->OnAckNotification(10, 20, 30, 40, zero_); |
427 | 427 |
428 // The arguments to delegate->OnAckNotification are the sum of the | 428 // The arguments to delegate->OnAckNotification are the sum of the |
429 // arguments to proxy_delegate OnAckNotification calls. | 429 // arguments to proxy_delegate OnAckNotification calls. |
430 EXPECT_CALL(*delegate, OnAckNotification(111, 222, 333, 444, zero_)); | 430 EXPECT_CALL(*delegate, OnAckNotification(111, 222, 333, 444, zero_)); |
(...skipping 11 matching lines...) Expand all Loading... |
442 const int kDataSize = 16 * 1024; | 442 const int kDataSize = 16 * 1024; |
443 const string kData(kDataSize, 'a'); | 443 const string kData(kDataSize, 'a'); |
444 | 444 |
445 const int kInitialWriteSize = 100; | 445 const int kInitialWriteSize = 100; |
446 | 446 |
447 // Set a large flow control send window so this doesn't interfere with test. | 447 // Set a large flow control send window so this doesn't interfere with test. |
448 stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1); | 448 stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1); |
449 | 449 |
450 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; | 450 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; |
451 | 451 |
452 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 452 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
453 WithArgs<4>(Invoke(CreateFunctor( | 453 .WillOnce(DoAll(WithArgs<4>(Invoke(CreateFunctor( |
454 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 454 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
455 Return(QuicConsumedData(kInitialWriteSize, false)))); | 455 Return(QuicConsumedData(kInitialWriteSize, false)))); |
456 stream_->WriteOrBufferData(kData, false, delegate.get()); | 456 stream_->WriteOrBufferData(kData, false, delegate.get()); |
457 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); | 457 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); |
458 | 458 |
459 // Handle the ack of the first write. | 459 // Handle the ack of the first write. |
460 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); | 460 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); |
461 proxy_delegate = NULL; | 461 proxy_delegate = NULL; |
462 | 462 |
463 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 463 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( |
464 WithArgs<4>(Invoke(CreateFunctor( | 464 DoAll(WithArgs<4>(Invoke( |
465 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 465 CreateFunctor(&SaveProxyAckNotifierDelegate, &proxy_delegate))), |
466 Return(QuicConsumedData(kDataSize - kInitialWriteSize, false)))); | 466 Return(QuicConsumedData(kDataSize - kInitialWriteSize, false)))); |
467 stream_->OnCanWrite(); | 467 stream_->OnCanWrite(); |
468 | 468 |
469 // Handle the ack for the second write. | 469 // Handle the ack for the second write. |
470 EXPECT_CALL(*delegate, OnAckNotification(101, 202, 303, 404, zero_)); | 470 EXPECT_CALL(*delegate, OnAckNotification(101, 202, 303, 404, zero_)); |
471 proxy_delegate->OnAckNotification(100, 200, 300, 400, zero_); | 471 proxy_delegate->OnAckNotification(100, 200, 300, 400, zero_); |
472 } | 472 } |
473 | 473 |
474 // Verify delegate behavior when WriteOrBufferData does not buffer. | 474 // Verify delegate behavior when WriteOrBufferData does not buffer. |
475 TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferNoBuffer) { | 475 TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferNoBuffer) { |
476 Initialize(kShouldProcessData); | 476 Initialize(kShouldProcessData); |
477 | 477 |
478 scoped_refptr<MockAckNotifierDelegate> delegate( | 478 scoped_refptr<MockAckNotifierDelegate> delegate( |
479 new StrictMock<MockAckNotifierDelegate>); | 479 new StrictMock<MockAckNotifierDelegate>); |
480 | 480 |
481 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; | 481 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; |
482 | 482 |
483 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 483 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
484 WithArgs<4>(Invoke(CreateFunctor( | 484 .WillOnce(DoAll(WithArgs<4>(Invoke(CreateFunctor( |
485 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 485 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
486 Return(QuicConsumedData(kDataLen, true)))); | 486 Return(QuicConsumedData(kDataLen, true)))); |
487 stream_->WriteOrBufferData(kData1, true, delegate.get()); | 487 stream_->WriteOrBufferData(kData1, true, delegate.get()); |
488 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); | 488 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); |
489 | 489 |
490 // Handle the ack. | 490 // Handle the ack. |
491 EXPECT_CALL(*delegate, OnAckNotification(1, 2, 3, 4, zero_)); | 491 EXPECT_CALL(*delegate, OnAckNotification(1, 2, 3, 4, zero_)); |
492 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); | 492 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); |
493 } | 493 } |
494 | 494 |
495 // Verify delegate behavior when WriteOrBufferData buffers all the data. | 495 // Verify delegate behavior when WriteOrBufferData buffers all the data. |
496 TEST_F(ReliableQuicStreamTest, BufferOnWriteAndBufferDataWithAckNotifer) { | 496 TEST_F(ReliableQuicStreamTest, BufferOnWriteAndBufferDataWithAckNotifer) { |
497 Initialize(kShouldProcessData); | 497 Initialize(kShouldProcessData); |
498 | 498 |
499 scoped_refptr<MockAckNotifierDelegate> delegate( | 499 scoped_refptr<MockAckNotifierDelegate> delegate( |
500 new StrictMock<MockAckNotifierDelegate>); | 500 new StrictMock<MockAckNotifierDelegate>); |
501 | 501 |
502 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; | 502 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; |
503 | 503 |
504 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 504 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
505 Return(QuicConsumedData(0, false))); | 505 .WillOnce(Return(QuicConsumedData(0, false))); |
506 stream_->WriteOrBufferData(kData1, true, delegate.get()); | 506 stream_->WriteOrBufferData(kData1, true, delegate.get()); |
507 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); | 507 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); |
508 | 508 |
509 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 509 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
510 WithArgs<4>(Invoke(CreateFunctor( | 510 .WillOnce(DoAll(WithArgs<4>(Invoke(CreateFunctor( |
511 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 511 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
512 Return(QuicConsumedData(kDataLen, true)))); | 512 Return(QuicConsumedData(kDataLen, true)))); |
513 stream_->OnCanWrite(); | 513 stream_->OnCanWrite(); |
514 | 514 |
515 // Handle the ack. | 515 // Handle the ack. |
516 EXPECT_CALL(*delegate, OnAckNotification(1, 2, 3, 4, zero_)); | 516 EXPECT_CALL(*delegate, OnAckNotification(1, 2, 3, 4, zero_)); |
517 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); | 517 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); |
518 } | 518 } |
519 | 519 |
520 // Verify delegate behavior when WriteOrBufferData when the FIN is | 520 // Verify delegate behavior when WriteOrBufferData when the FIN is |
521 // sent out in a different packet. | 521 // sent out in a different packet. |
522 TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferOnlyFinRemains) { | 522 TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferOnlyFinRemains) { |
523 Initialize(kShouldProcessData); | 523 Initialize(kShouldProcessData); |
524 | 524 |
525 scoped_refptr<MockAckNotifierDelegate> delegate( | 525 scoped_refptr<MockAckNotifierDelegate> delegate( |
526 new StrictMock<MockAckNotifierDelegate>); | 526 new StrictMock<MockAckNotifierDelegate>); |
527 | 527 |
528 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; | 528 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; |
529 | 529 |
530 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 530 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
531 WithArgs<4>(Invoke(CreateFunctor( | 531 .WillOnce(DoAll(WithArgs<4>(Invoke(CreateFunctor( |
532 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 532 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
533 Return(QuicConsumedData(kDataLen, false)))); | 533 Return(QuicConsumedData(kDataLen, false)))); |
534 stream_->WriteOrBufferData(kData1, true, delegate.get()); | 534 stream_->WriteOrBufferData(kData1, true, delegate.get()); |
535 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); | 535 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); |
536 | 536 |
537 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 537 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
538 WithArgs<4>(Invoke(CreateFunctor( | 538 .WillOnce(DoAll(WithArgs<4>(Invoke(CreateFunctor( |
539 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 539 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
540 Return(QuicConsumedData(0, true)))); | 540 Return(QuicConsumedData(0, true)))); |
541 stream_->OnCanWrite(); | 541 stream_->OnCanWrite(); |
542 | 542 |
543 // Handle the acks. | 543 // Handle the acks. |
544 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); | 544 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); |
545 EXPECT_CALL(*delegate, OnAckNotification(11, 22, 33, 44, zero_)); | 545 EXPECT_CALL(*delegate, OnAckNotification(11, 22, 33, 44, zero_)); |
546 proxy_delegate->OnAckNotification(10, 20, 30, 40, zero_); | 546 proxy_delegate->OnAckNotification(10, 20, 30, 40, zero_); |
547 } | 547 } |
548 | 548 |
549 } // namespace | 549 } // namespace |
550 } // namespace test | 550 } // namespace test |
551 } // namespace net | 551 } // namespace net |
OLD | NEW |