| 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 |