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 |