| 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 19 matching lines...) Expand all Loading... |
| 30 using testing::WithArgs; | 30 using testing::WithArgs; |
| 31 using testing::_; | 31 using testing::_; |
| 32 | 32 |
| 33 namespace net { | 33 namespace net { |
| 34 namespace test { | 34 namespace test { |
| 35 namespace { | 35 namespace { |
| 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 QuicStreamId 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, |
| 47 QuicSession* session, | 47 QuicSession* session, |
| 48 bool should_process_data) | 48 bool should_process_data) |
| 49 : ReliableQuicStream(id, session), | 49 : ReliableQuicStream(id, session), |
| 50 should_process_data_(should_process_data) {} | 50 should_process_data_(should_process_data) {} |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 QuicSessionPeer::GetWriteblockedStreams(session_.get()); | 127 QuicSessionPeer::GetWriteblockedStreams(session_.get()); |
| 128 } | 128 } |
| 129 | 129 |
| 130 bool fin_sent() { return ReliableQuicStreamPeer::FinSent(stream_.get()); } | 130 bool fin_sent() { return ReliableQuicStreamPeer::FinSent(stream_.get()); } |
| 131 bool rst_sent() { return ReliableQuicStreamPeer::RstSent(stream_.get()); } | 131 bool rst_sent() { return ReliableQuicStreamPeer::RstSent(stream_.get()); } |
| 132 | 132 |
| 133 void set_initial_flow_control_window_bytes(uint32 val) { | 133 void set_initial_flow_control_window_bytes(uint32 val) { |
| 134 initial_flow_control_window_bytes_ = val; | 134 initial_flow_control_window_bytes_ = val; |
| 135 } | 135 } |
| 136 | 136 |
| 137 bool HasWriteBlockedStreams() { |
| 138 return write_blocked_list_->HasWriteBlockedCryptoOrHeadersStream() || |
| 139 write_blocked_list_->HasWriteBlockedDataStreams(); |
| 140 } |
| 141 |
| 137 protected: | 142 protected: |
| 138 MockConnection* connection_; | 143 MockConnection* connection_; |
| 139 scoped_ptr<MockSession> session_; | 144 scoped_ptr<MockSession> session_; |
| 140 scoped_ptr<TestStream> stream_; | 145 scoped_ptr<TestStream> stream_; |
| 141 scoped_ptr<TestStream> stream2_; | 146 scoped_ptr<TestStream> stream2_; |
| 142 SpdyHeaderBlock headers_; | 147 SpdyHeaderBlock headers_; |
| 143 QuicWriteBlockedList* write_blocked_list_; | 148 QuicWriteBlockedList* write_blocked_list_; |
| 144 uint32 initial_flow_control_window_bytes_; | 149 uint32 initial_flow_control_window_bytes_; |
| 145 QuicTime::Delta zero_; | 150 QuicTime::Delta zero_; |
| 146 QuicVersionVector supported_versions_; | 151 QuicVersionVector supported_versions_; |
| 147 }; | 152 }; |
| 148 | 153 |
| 149 TEST_F(ReliableQuicStreamTest, WriteAllData) { | 154 TEST_F(ReliableQuicStreamTest, WriteAllData) { |
| 150 Initialize(kShouldProcessData); | 155 Initialize(kShouldProcessData); |
| 151 | 156 |
| 152 connection_->options()->max_packet_length = | 157 connection_->options()->max_packet_length = |
| 153 1 + QuicPacketCreator::StreamFramePacketOverhead( | 158 1 + QuicPacketCreator::StreamFramePacketOverhead( |
| 154 connection_->version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | 159 connection_->version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
| 155 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | 160 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); |
| 156 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 161 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( |
| 157 Return(QuicConsumedData(kDataLen, true))); | 162 Return(QuicConsumedData(kDataLen, true))); |
| 158 stream_->WriteOrBufferData(kData1, false, NULL); | 163 stream_->WriteOrBufferData(kData1, false, NULL); |
| 159 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); | 164 EXPECT_FALSE(HasWriteBlockedStreams()); |
| 160 } | 165 } |
| 161 | 166 |
| 162 TEST_F(ReliableQuicStreamTest, NoBlockingIfNoDataOrFin) { | 167 TEST_F(ReliableQuicStreamTest, NoBlockingIfNoDataOrFin) { |
| 163 Initialize(kShouldProcessData); | 168 Initialize(kShouldProcessData); |
| 164 | 169 |
| 165 // Write no data and no fin. If we consume nothing we should not be write | 170 // Write no data and no fin. If we consume nothing we should not be write |
| 166 // blocked. | 171 // blocked. |
| 167 EXPECT_DFATAL(stream_->WriteOrBufferData(StringPiece(), false, NULL), ""); | 172 EXPECT_DFATAL(stream_->WriteOrBufferData(StringPiece(), false, NULL), ""); |
| 168 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); | 173 EXPECT_FALSE(HasWriteBlockedStreams()); |
| 169 } | 174 } |
| 170 | 175 |
| 171 TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) { | 176 TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) { |
| 172 Initialize(kShouldProcessData); | 177 Initialize(kShouldProcessData); |
| 173 | 178 |
| 174 // Write some data and no fin. If we consume some but not all of the data, | 179 // 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. | 180 // we should be write blocked a not all the data was consumed. |
| 176 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 181 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( |
| 177 Return(QuicConsumedData(1, false))); | 182 Return(QuicConsumedData(1, false))); |
| 178 stream_->WriteOrBufferData(StringPiece(kData1, 2), false, NULL); | 183 stream_->WriteOrBufferData(StringPiece(kData1, 2), false, NULL); |
| 179 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); | 184 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); |
| 180 } | 185 } |
| 181 | 186 |
| 182 | |
| 183 TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) { | 187 TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) { |
| 184 Initialize(kShouldProcessData); | 188 Initialize(kShouldProcessData); |
| 185 | 189 |
| 186 // Write some data and no fin. If we consume all the data but not the fin, | 190 // 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. | 191 // 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 | 192 // (This should never actually happen as the fin should be sent out with the |
| 189 // last data) | 193 // last data) |
| 190 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 194 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( |
| 191 Return(QuicConsumedData(2, false))); | 195 Return(QuicConsumedData(2, false))); |
| 192 stream_->WriteOrBufferData(StringPiece(kData1, 2), true, NULL); | 196 stream_->WriteOrBufferData(StringPiece(kData1, 2), true, NULL); |
| 193 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); | 197 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); |
| 194 } | 198 } |
| 195 | 199 |
| 196 TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) { | 200 TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) { |
| 197 Initialize(kShouldProcessData); | 201 Initialize(kShouldProcessData); |
| 198 | 202 |
| 199 // Write no data and a fin. If we consume nothing we should be write blocked, | 203 // Write no data and a fin. If we consume nothing we should be write blocked, |
| 200 // as the fin was not consumed. | 204 // as the fin was not consumed. |
| 201 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 205 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( |
| 202 Return(QuicConsumedData(0, false))); | 206 Return(QuicConsumedData(0, false))); |
| 203 stream_->WriteOrBufferData(StringPiece(), true, NULL); | 207 stream_->WriteOrBufferData(StringPiece(), true, NULL); |
| 204 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); | 208 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); |
| 205 } | 209 } |
| 206 | 210 |
| 207 TEST_F(ReliableQuicStreamTest, WriteOrBufferData) { | 211 TEST_F(ReliableQuicStreamTest, WriteOrBufferData) { |
| 208 Initialize(kShouldProcessData); | 212 Initialize(kShouldProcessData); |
| 209 | 213 |
| 210 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); | 214 EXPECT_FALSE(HasWriteBlockedStreams()); |
| 211 connection_->options()->max_packet_length = | 215 connection_->options()->max_packet_length = |
| 212 1 + QuicPacketCreator::StreamFramePacketOverhead( | 216 1 + QuicPacketCreator::StreamFramePacketOverhead( |
| 213 connection_->version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, | 217 connection_->version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
| 214 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); | 218 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); |
| 215 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).WillOnce( | 219 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).WillOnce( |
| 216 Return(QuicConsumedData(kDataLen - 1, false))); | 220 Return(QuicConsumedData(kDataLen - 1, false))); |
| 217 stream_->WriteOrBufferData(kData1, false, NULL); | 221 stream_->WriteOrBufferData(kData1, false, NULL); |
| 218 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); | 222 EXPECT_TRUE(HasWriteBlockedStreams()); |
| 219 | 223 |
| 220 // Queue a bytes_consumed write. | 224 // Queue a bytes_consumed write. |
| 221 stream_->WriteOrBufferData(kData2, false, NULL); | 225 stream_->WriteOrBufferData(kData2, false, NULL); |
| 222 | 226 |
| 223 // Make sure we get the tail of the first write followed by the bytes_consumed | 227 // Make sure we get the tail of the first write followed by the bytes_consumed |
| 224 InSequence s; | 228 InSequence s; |
| 225 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)). | 229 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)). |
| 226 WillOnce(Return(QuicConsumedData(1, false))); | 230 WillOnce(Return(QuicConsumedData(1, false))); |
| 227 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)). | 231 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)). |
| 228 WillOnce(Return(QuicConsumedData(kDataLen - 2, false))); | 232 WillOnce(Return(QuicConsumedData(kDataLen - 2, false))); |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 session_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1); | 402 session_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1); |
| 399 } | 403 } |
| 400 | 404 |
| 401 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; | 405 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; |
| 402 | 406 |
| 403 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 407 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( |
| 404 WithArgs<4>(Invoke(CreateFunctor( | 408 WithArgs<4>(Invoke(CreateFunctor( |
| 405 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 409 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
| 406 Return(QuicConsumedData(kFirstWriteSize, false)))); | 410 Return(QuicConsumedData(kFirstWriteSize, false)))); |
| 407 stream_->WriteOrBufferData(kData, false, delegate.get()); | 411 stream_->WriteOrBufferData(kData, false, delegate.get()); |
| 408 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); | 412 EXPECT_TRUE(HasWriteBlockedStreams()); |
| 409 | 413 |
| 410 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())). | 414 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())). |
| 411 WillOnce( | 415 WillOnce( |
| 412 Return(QuicConsumedData(kSecondWriteSize, false))); | 416 Return(QuicConsumedData(kSecondWriteSize, false))); |
| 413 stream_->OnCanWrite(); | 417 stream_->OnCanWrite(); |
| 414 | 418 |
| 415 // No ack expected for an empty write. | 419 // No ack expected for an empty write. |
| 416 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())). | 420 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())). |
| 417 WillOnce( | 421 WillOnce( |
| 418 Return(QuicConsumedData(0, false))); | 422 Return(QuicConsumedData(0, false))); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 session_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1); | 457 session_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1); |
| 454 } | 458 } |
| 455 | 459 |
| 456 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; | 460 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; |
| 457 | 461 |
| 458 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 462 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( |
| 459 WithArgs<4>(Invoke(CreateFunctor( | 463 WithArgs<4>(Invoke(CreateFunctor( |
| 460 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 464 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
| 461 Return(QuicConsumedData(kInitialWriteSize, false)))); | 465 Return(QuicConsumedData(kInitialWriteSize, false)))); |
| 462 stream_->WriteOrBufferData(kData, false, delegate.get()); | 466 stream_->WriteOrBufferData(kData, false, delegate.get()); |
| 463 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); | 467 EXPECT_TRUE(HasWriteBlockedStreams()); |
| 464 | 468 |
| 465 // Handle the ack of the first write. | 469 // Handle the ack of the first write. |
| 466 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); | 470 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); |
| 467 proxy_delegate = NULL; | 471 proxy_delegate = NULL; |
| 468 | 472 |
| 469 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 473 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( |
| 470 WithArgs<4>(Invoke(CreateFunctor( | 474 WithArgs<4>(Invoke(CreateFunctor( |
| 471 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 475 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
| 472 Return(QuicConsumedData(kDataSize - kInitialWriteSize, false)))); | 476 Return(QuicConsumedData(kDataSize - kInitialWriteSize, false)))); |
| 473 stream_->OnCanWrite(); | 477 stream_->OnCanWrite(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 484 scoped_refptr<MockAckNotifierDelegate> delegate( | 488 scoped_refptr<MockAckNotifierDelegate> delegate( |
| 485 new StrictMock<MockAckNotifierDelegate>); | 489 new StrictMock<MockAckNotifierDelegate>); |
| 486 | 490 |
| 487 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; | 491 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; |
| 488 | 492 |
| 489 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 493 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( |
| 490 WithArgs<4>(Invoke(CreateFunctor( | 494 WithArgs<4>(Invoke(CreateFunctor( |
| 491 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 495 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
| 492 Return(QuicConsumedData(kDataLen, true)))); | 496 Return(QuicConsumedData(kDataLen, true)))); |
| 493 stream_->WriteOrBufferData(kData1, true, delegate.get()); | 497 stream_->WriteOrBufferData(kData1, true, delegate.get()); |
| 494 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); | 498 EXPECT_FALSE(HasWriteBlockedStreams()); |
| 495 | 499 |
| 496 // Handle the ack. | 500 // Handle the ack. |
| 497 EXPECT_CALL(*delegate, OnAckNotification(1, 2, 3, 4, zero_)); | 501 EXPECT_CALL(*delegate, OnAckNotification(1, 2, 3, 4, zero_)); |
| 498 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); | 502 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); |
| 499 } | 503 } |
| 500 | 504 |
| 501 // Verify delegate behavior when WriteOrBufferData buffers all the data. | 505 // Verify delegate behavior when WriteOrBufferData buffers all the data. |
| 502 TEST_F(ReliableQuicStreamTest, BufferOnWriteAndBufferDataWithAckNotifer) { | 506 TEST_F(ReliableQuicStreamTest, BufferOnWriteAndBufferDataWithAckNotifer) { |
| 503 Initialize(kShouldProcessData); | 507 Initialize(kShouldProcessData); |
| 504 | 508 |
| 505 scoped_refptr<MockAckNotifierDelegate> delegate( | 509 scoped_refptr<MockAckNotifierDelegate> delegate( |
| 506 new StrictMock<MockAckNotifierDelegate>); | 510 new StrictMock<MockAckNotifierDelegate>); |
| 507 | 511 |
| 508 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; | 512 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; |
| 509 | 513 |
| 510 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 514 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( |
| 511 Return(QuicConsumedData(0, false))); | 515 Return(QuicConsumedData(0, false))); |
| 512 stream_->WriteOrBufferData(kData1, true, delegate.get()); | 516 stream_->WriteOrBufferData(kData1, true, delegate.get()); |
| 513 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); | 517 EXPECT_TRUE(HasWriteBlockedStreams()); |
| 514 | 518 |
| 515 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 519 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( |
| 516 WithArgs<4>(Invoke(CreateFunctor( | 520 WithArgs<4>(Invoke(CreateFunctor( |
| 517 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 521 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
| 518 Return(QuicConsumedData(kDataLen, true)))); | 522 Return(QuicConsumedData(kDataLen, true)))); |
| 519 stream_->OnCanWrite(); | 523 stream_->OnCanWrite(); |
| 520 | 524 |
| 521 // Handle the ack. | 525 // Handle the ack. |
| 522 EXPECT_CALL(*delegate, OnAckNotification(1, 2, 3, 4, zero_)); | 526 EXPECT_CALL(*delegate, OnAckNotification(1, 2, 3, 4, zero_)); |
| 523 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); | 527 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); |
| 524 } | 528 } |
| 525 | 529 |
| 526 // Verify delegate behavior when WriteOrBufferData when the FIN is | 530 // Verify delegate behavior when WriteOrBufferData when the FIN is |
| 527 // sent out in a different packet. | 531 // sent out in a different packet. |
| 528 TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferOnlyFinRemains) { | 532 TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferOnlyFinRemains) { |
| 529 Initialize(kShouldProcessData); | 533 Initialize(kShouldProcessData); |
| 530 | 534 |
| 531 scoped_refptr<MockAckNotifierDelegate> delegate( | 535 scoped_refptr<MockAckNotifierDelegate> delegate( |
| 532 new StrictMock<MockAckNotifierDelegate>); | 536 new StrictMock<MockAckNotifierDelegate>); |
| 533 | 537 |
| 534 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; | 538 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate; |
| 535 | 539 |
| 536 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 540 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( |
| 537 WithArgs<4>(Invoke(CreateFunctor( | 541 WithArgs<4>(Invoke(CreateFunctor( |
| 538 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 542 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
| 539 Return(QuicConsumedData(kDataLen, false)))); | 543 Return(QuicConsumedData(kDataLen, false)))); |
| 540 stream_->WriteOrBufferData(kData1, true, delegate.get()); | 544 stream_->WriteOrBufferData(kData1, true, delegate.get()); |
| 541 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); | 545 EXPECT_TRUE(HasWriteBlockedStreams()); |
| 542 | 546 |
| 543 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( | 547 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll( |
| 544 WithArgs<4>(Invoke(CreateFunctor( | 548 WithArgs<4>(Invoke(CreateFunctor( |
| 545 &SaveProxyAckNotifierDelegate, &proxy_delegate))), | 549 &SaveProxyAckNotifierDelegate, &proxy_delegate))), |
| 546 Return(QuicConsumedData(0, true)))); | 550 Return(QuicConsumedData(0, true)))); |
| 547 stream_->OnCanWrite(); | 551 stream_->OnCanWrite(); |
| 548 | 552 |
| 549 // Handle the acks. | 553 // Handle the acks. |
| 550 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); | 554 proxy_delegate->OnAckNotification(1, 2, 3, 4, zero_); |
| 551 EXPECT_CALL(*delegate, OnAckNotification(11, 22, 33, 44, zero_)); | 555 EXPECT_CALL(*delegate, OnAckNotification(11, 22, 33, 44, zero_)); |
| 552 proxy_delegate->OnAckNotification(10, 20, 30, 40, zero_); | 556 proxy_delegate->OnAckNotification(10, 20, 30, 40, zero_); |
| 553 } | 557 } |
| 554 | 558 |
| 555 } // namespace | 559 } // namespace |
| 556 } // namespace test | 560 } // namespace test |
| 557 } // namespace net | 561 } // namespace net |
| OLD | NEW |