| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/quic_data_stream.h" | 5 #include "net/quic/quic_data_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" |
| 11 #include "net/quic/quic_write_blocked_list.h" | 11 #include "net/quic/quic_write_blocked_list.h" |
| 12 #include "net/quic/spdy_utils.h" | 12 #include "net/quic/spdy_utils.h" |
| 13 #include "net/quic/test_tools/quic_flow_controller_peer.h" |
| 13 #include "net/quic/test_tools/quic_session_peer.h" | 14 #include "net/quic/test_tools/quic_session_peer.h" |
| 14 #include "net/quic/test_tools/quic_test_utils.h" | 15 #include "net/quic/test_tools/quic_test_utils.h" |
| 15 #include "net/quic/test_tools/reliable_quic_stream_peer.h" | 16 #include "net/quic/test_tools/reliable_quic_stream_peer.h" |
| 16 #include "net/test/gtest_util.h" | 17 #include "net/test/gtest_util.h" |
| 17 #include "testing/gmock/include/gmock/gmock.h" | 18 #include "testing/gmock/include/gmock/gmock.h" |
| 18 | 19 |
| 19 using base::StringPiece; | 20 using base::StringPiece; |
| 20 using std::min; | 21 using std::min; |
| 21 using testing::_; | 22 using testing::_; |
| 22 using testing::AnyNumber; | 23 using testing::AnyNumber; |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 // but are flow control blocked. | 285 // but are flow control blocked. |
| 285 if (GetParam() < QUIC_VERSION_17) { | 286 if (GetParam() < QUIC_VERSION_17) { |
| 286 return; | 287 return; |
| 287 } | 288 } |
| 288 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control, true); | 289 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control, true); |
| 289 | 290 |
| 290 Initialize(kShouldProcessData); | 291 Initialize(kShouldProcessData); |
| 291 | 292 |
| 292 // Set a small flow control limit. | 293 // Set a small flow control limit. |
| 293 const uint64 kWindow = 36; | 294 const uint64 kWindow = 36; |
| 294 ReliableQuicStreamPeer::SetFlowControlSendOffset(stream_.get(), kWindow); | 295 QuicFlowControllerPeer::SetSendWindowOffset(stream_.get()->flow_controller(), |
| 295 EXPECT_EQ(kWindow, ReliableQuicStreamPeer::SendWindowSize(stream_.get())); | 296 kWindow); |
| 297 EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset( |
| 298 stream_.get()->flow_controller())); |
| 296 | 299 |
| 297 // Try to send more data than the flow control limit allows. | 300 // Try to send more data than the flow control limit allows. |
| 298 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 301 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 299 string body; | 302 string body; |
| 300 const uint64 kOverflow = 15; | 303 const uint64 kOverflow = 15; |
| 301 GenerateBody(&body, kWindow + kOverflow); | 304 GenerateBody(&body, kWindow + kOverflow); |
| 302 | 305 |
| 303 EXPECT_CALL(*connection_, SendBlocked(kStreamId)); | 306 EXPECT_CALL(*connection_, SendBlocked(kStreamId)); |
| 304 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 307 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( |
| 305 Return(QuicConsumedData(kWindow, true))); | 308 Return(QuicConsumedData(kWindow, true))); |
| 306 stream_->WriteOrBufferData(body, false, NULL); | 309 stream_->WriteOrBufferData(body, false, NULL); |
| 307 | 310 |
| 308 // Should have sent as much as possible, resulting in no send window left. | 311 // Should have sent as much as possible, resulting in no send window left. |
| 309 EXPECT_EQ(0u, ReliableQuicStreamPeer::SendWindowSize(stream_.get())); | 312 EXPECT_EQ(0u, QuicFlowControllerPeer::SendWindowSize( |
| 313 stream_.get()->flow_controller())); |
| 310 | 314 |
| 311 // And we should have queued the overflowed data. | 315 // And we should have queued the overflowed data. |
| 312 EXPECT_EQ(kOverflow, | 316 EXPECT_EQ(kOverflow, |
| 313 ReliableQuicStreamPeer::SizeOfQueuedData(stream_.get())); | 317 ReliableQuicStreamPeer::SizeOfQueuedData(stream_.get())); |
| 314 } | 318 } |
| 315 | 319 |
| 316 TEST_P(QuicDataStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) { | 320 TEST_P(QuicDataStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) { |
| 317 // The flow control receive window decreases whenever we add new bytes to the | 321 // The flow control receive window decreases whenever we add new bytes to the |
| 318 // sequencer, whether they are consumed immediately or buffered. However we | 322 // sequencer, whether they are consumed immediately or buffered. However we |
| 319 // only send WINDOW_UPDATE frames based on increasing number of bytes | 323 // only send WINDOW_UPDATE frames based on increasing number of bytes |
| 320 // consumed. | 324 // consumed. |
| 321 if (GetParam() < QUIC_VERSION_17) { | 325 if (GetParam() < QUIC_VERSION_17) { |
| 322 return; | 326 return; |
| 323 } | 327 } |
| 324 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control, true); | 328 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control, true); |
| 325 | 329 |
| 326 // Don't process data - it will be buffered instead. | 330 // Don't process data - it will be buffered instead. |
| 327 Initialize(!kShouldProcessData); | 331 Initialize(!kShouldProcessData); |
| 328 | 332 |
| 329 // Expect no WINDOW_UPDATE frames to be sent. | 333 // Expect no WINDOW_UPDATE frames to be sent. |
| 330 EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0); | 334 EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0); |
| 331 | 335 |
| 332 // Set a small flow control limit. | 336 // Set a small flow control receive window. |
| 333 const uint64 kWindow = 36; | 337 const uint64 kWindow = 36; |
| 334 ReliableQuicStreamPeer::SetFlowControlReceiveOffset(stream_.get(), | 338 QuicFlowControllerPeer::SetReceiveWindowOffset( |
| 335 kWindow); | 339 stream_.get()->flow_controller(), kWindow); |
| 336 ReliableQuicStreamPeer::SetFlowControlMaxReceiveWindow(stream_.get(), | 340 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_.get()->flow_controller(), |
| 337 kWindow); | 341 kWindow); |
| 338 EXPECT_EQ(kWindow, ReliableQuicStreamPeer::ReceiveWindowSize(stream_.get())); | 342 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( |
| 343 stream_.get()->flow_controller())); |
| 339 | 344 |
| 340 // Stream receives enough data to fill a fraction of the receive window. | 345 // Stream receives enough data to fill a fraction of the receive window. |
| 341 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 346 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 342 string body; | 347 string body; |
| 343 GenerateBody(&body, kWindow / 3); | 348 GenerateBody(&body, kWindow / 3); |
| 344 stream_->OnStreamHeaders(headers); | 349 stream_->OnStreamHeaders(headers); |
| 345 EXPECT_EQ(headers, stream_->data()); | 350 EXPECT_EQ(headers, stream_->data()); |
| 346 stream_->OnStreamHeadersComplete(false, headers.size()); | 351 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 347 | 352 |
| 348 QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(body)); | 353 QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(body)); |
| 349 stream_->OnStreamFrame(frame1); | 354 stream_->OnStreamFrame(frame1); |
| 350 EXPECT_EQ(kWindow - (kWindow / 3), | 355 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( |
| 351 ReliableQuicStreamPeer::ReceiveWindowSize(stream_.get())); | 356 stream_.get()->flow_controller())); |
| 352 | 357 |
| 353 // Now receive another frame which results in the receive window being over | 358 // Now receive another frame which results in the receive window being over |
| 354 // half full. This should all be buffered, decreasing the receive window but | 359 // half full. This should all be buffered, decreasing the receive window but |
| 355 // not sending WINDOW_UPDATE. | 360 // not sending WINDOW_UPDATE. |
| 356 QuicStreamFrame frame2(kStreamId, false, kWindow / 3, MakeIOVector(body)); | 361 QuicStreamFrame frame2(kStreamId, false, kWindow / 3, MakeIOVector(body)); |
| 357 stream_->OnStreamFrame(frame2); | 362 stream_->OnStreamFrame(frame2); |
| 358 EXPECT_EQ(kWindow - (2 * kWindow / 3), | 363 EXPECT_EQ(kWindow - (2 * kWindow / 3), |
| 359 ReliableQuicStreamPeer::ReceiveWindowSize(stream_.get())); | 364 QuicFlowControllerPeer::ReceiveWindowSize( |
| 365 stream_.get()->flow_controller())); |
| 360 } | 366 } |
| 361 | 367 |
| 362 TEST_P(QuicDataStreamTest, StreamFlowControlWindowUpdate) { | 368 TEST_P(QuicDataStreamTest, StreamFlowControlWindowUpdate) { |
| 363 // Tests that on receipt of data, the stream updates its receive window offset | 369 // Tests that on receipt of data, the stream updates its receive window offset |
| 364 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops | 370 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops |
| 365 // too low. | 371 // too low. |
| 366 if (GetParam() < QUIC_VERSION_17) { | 372 if (GetParam() < QUIC_VERSION_17) { |
| 367 return; | 373 return; |
| 368 } | 374 } |
| 369 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control, true); | 375 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control, true); |
| 370 | 376 |
| 371 Initialize(kShouldProcessData); | 377 Initialize(kShouldProcessData); |
| 372 | 378 |
| 373 // Set a small flow control limit. | 379 // Set a small flow control limit. |
| 374 const uint64 kWindow = 36; | 380 const uint64 kWindow = 36; |
| 375 ReliableQuicStreamPeer::SetFlowControlReceiveOffset(stream_.get(), | 381 QuicFlowControllerPeer::SetReceiveWindowOffset( |
| 376 kWindow); | 382 stream_.get()->flow_controller(), kWindow); |
| 377 ReliableQuicStreamPeer::SetFlowControlMaxReceiveWindow(stream_.get(), | 383 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_.get()->flow_controller(), |
| 378 kWindow); | 384 kWindow); |
| 379 EXPECT_EQ(kWindow, ReliableQuicStreamPeer::ReceiveWindowSize(stream_.get())); | 385 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( |
| 386 stream_.get()->flow_controller())); |
| 380 | 387 |
| 381 // Stream receives enough data to fill a fraction of the receive window. | 388 // Stream receives enough data to fill a fraction of the receive window. |
| 382 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 389 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 383 string body; | 390 string body; |
| 384 GenerateBody(&body, kWindow / 3); | 391 GenerateBody(&body, kWindow / 3); |
| 385 stream_->OnStreamHeaders(headers); | 392 stream_->OnStreamHeaders(headers); |
| 386 EXPECT_EQ(headers, stream_->data()); | 393 EXPECT_EQ(headers, stream_->data()); |
| 387 stream_->OnStreamHeadersComplete(false, headers.size()); | 394 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 388 | 395 |
| 389 QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(body)); | 396 QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(body)); |
| 390 stream_->OnStreamFrame(frame1); | 397 stream_->OnStreamFrame(frame1); |
| 391 EXPECT_EQ(kWindow - (kWindow / 3), | 398 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( |
| 392 ReliableQuicStreamPeer::ReceiveWindowSize(stream_.get())); | 399 stream_.get()->flow_controller())); |
| 393 | 400 |
| 394 // Now receive another frame which results in the receive window being over | 401 // Now receive another frame which results in the receive window being over |
| 395 // half full. This will trigger the stream to increase its receive window | 402 // half full. This will trigger the stream to increase its receive window |
| 396 // offset and send a WINDOW_UPDATE. The result will be again an available | 403 // offset and send a WINDOW_UPDATE. The result will be again an available |
| 397 // window of kWindow bytes. | 404 // window of kWindow bytes. |
| 398 QuicStreamFrame frame2(kStreamId, false, kWindow / 3, MakeIOVector(body)); | 405 QuicStreamFrame frame2(kStreamId, false, kWindow / 3, MakeIOVector(body)); |
| 399 EXPECT_CALL( | 406 EXPECT_CALL( |
| 400 *connection_, | 407 *connection_, |
| 401 SendWindowUpdate( | 408 SendWindowUpdate(kStreamId, QuicFlowControllerPeer::ReceiveWindowOffset( |
| 402 kStreamId, | 409 stream_.get()->flow_controller()) + |
| 403 ReliableQuicStreamPeer::ReceiveWindowSize(stream_.get()) + kWindow)); | 410 2 * kWindow / 3)); |
| 404 stream_->OnStreamFrame(frame2); | 411 stream_->OnStreamFrame(frame2); |
| 405 EXPECT_EQ(kWindow, | 412 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize( |
| 406 ReliableQuicStreamPeer::ReceiveWindowSize(stream_.get())); | 413 stream_.get()->flow_controller())); |
| 407 } | 414 } |
| 408 | 415 |
| 409 TEST_P(QuicDataStreamTest, StreamFlowControlViolation) { | 416 TEST_P(QuicDataStreamTest, StreamFlowControlViolation) { |
| 410 // Tests that on if the peer sends too much data (i.e. violates the flow | 417 // Tests that on if the peer sends too much data (i.e. violates the flow |
| 411 // control protocol), then we terminate the connection. | 418 // control protocol), then we terminate the connection. |
| 412 if (GetParam() < QUIC_VERSION_17) { | 419 if (GetParam() < QUIC_VERSION_17) { |
| 413 return; | 420 return; |
| 414 } | 421 } |
| 415 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control, true); | 422 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control, true); |
| 416 | 423 |
| 417 // Stream should not process data, so that data gets buffered in the | 424 // Stream should not process data, so that data gets buffered in the |
| 418 // sequencer, triggering flow control limits. | 425 // sequencer, triggering flow control limits. |
| 419 Initialize(!kShouldProcessData); | 426 Initialize(!kShouldProcessData); |
| 420 | 427 |
| 421 // Set a small flow control limit. | 428 // Set a small flow control limit. |
| 422 const uint64 kWindow = 50; | 429 const uint64 kWindow = 50; |
| 423 ReliableQuicStreamPeer::SetFlowControlReceiveOffset(stream_.get(), | 430 QuicFlowControllerPeer::SetReceiveWindowOffset( |
| 424 kWindow); | 431 stream_.get()->flow_controller(), kWindow); |
| 425 | 432 |
| 426 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 433 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 427 string body; | |
| 428 GenerateBody(&body, kWindow + 1); | |
| 429 | |
| 430 stream_->OnStreamHeaders(headers); | 434 stream_->OnStreamHeaders(headers); |
| 431 EXPECT_EQ(headers, stream_->data()); | 435 EXPECT_EQ(headers, stream_->data()); |
| 432 stream_->OnStreamHeadersComplete(false, headers.size()); | 436 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 433 | 437 |
| 434 // Receive data to overflow the window, violating flow control. | 438 // Receive data to overflow the window, violating flow control. |
| 439 string body; |
| 440 GenerateBody(&body, kWindow + 1); |
| 435 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body)); | 441 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body)); |
| 436 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_FLOW_CONTROL_ERROR)); | 442 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_FLOW_CONTROL_ERROR)); |
| 437 EXPECT_DFATAL(stream_->OnStreamFrame(frame), | 443 EXPECT_DFATAL(stream_->OnStreamFrame(frame), |
| 438 "Server: Flow control violation on stream: 3, our receive " | 444 "Server: Flow control violation on stream 3, receive window: " |
| 439 "offset is: 50, we have consumed: 0, we have buffered: 51, " | 445 "50, bytes received: 51"); |
| 440 "total: 51"); | |
| 441 } | 446 } |
| 442 | 447 |
| 443 TEST_P(QuicDataStreamTest, StreamFlowControlFinNotBlocked) { | 448 TEST_P(QuicDataStreamTest, StreamFlowControlFinNotBlocked) { |
| 444 // An attempt to write a FIN with no data should not be flow control blocked, | 449 // An attempt to write a FIN with no data should not be flow control blocked, |
| 445 // even if the send window is 0. | 450 // even if the send window is 0. |
| 446 if (GetParam() < QUIC_VERSION_17) { | 451 if (GetParam() < QUIC_VERSION_17) { |
| 447 return; | 452 return; |
| 448 } | 453 } |
| 449 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control, true); | 454 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control, true); |
| 450 | 455 |
| 451 Initialize(kShouldProcessData); | 456 Initialize(kShouldProcessData); |
| 452 | 457 |
| 453 // Set a flow control limit of zero. | 458 // Set a flow control limit of zero. |
| 454 ReliableQuicStreamPeer::SetFlowControlReceiveOffset(stream_.get(), 0); | 459 QuicFlowControllerPeer::SetReceiveWindowOffset( |
| 455 EXPECT_EQ(0u, ReliableQuicStreamPeer::ReceiveWindowSize(stream_.get())); | 460 stream_.get()->flow_controller(), 0); |
| 461 EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset( |
| 462 stream_.get()->flow_controller())); |
| 456 | 463 |
| 457 // Send a frame with a FIN but no data. This should not be blocked. | 464 // Send a frame with a FIN but no data. This should not be blocked. |
| 458 string body = ""; | 465 string body = ""; |
| 459 bool fin = true; | 466 bool fin = true; |
| 460 | 467 |
| 461 EXPECT_CALL(*connection_, SendBlocked(kStreamId)).Times(0); | 468 EXPECT_CALL(*connection_, SendBlocked(kStreamId)).Times(0); |
| 462 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 469 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( |
| 463 Return(QuicConsumedData(0, fin))); | 470 Return(QuicConsumedData(0, fin))); |
| 464 | 471 |
| 465 stream_->WriteOrBufferData(body, fin, NULL); | 472 stream_->WriteOrBufferData(body, fin, NULL); |
| 466 } | 473 } |
| 467 | 474 |
| 468 } // namespace | 475 } // namespace |
| 469 } // namespace test | 476 } // namespace test |
| 470 } // namespace net | 477 } // namespace net |
| OLD | NEW |