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 <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "net/quic/congestion_control/rtt_stats.h" | 9 #include "net/quic/congestion_control/rtt_stats.h" |
10 #include "net/quic/congestion_control/tcp_cubic_sender.h" | 10 #include "net/quic/congestion_control/tcp_cubic_sender.h" |
11 #include "net/quic/congestion_control/tcp_receiver.h" | 11 #include "net/quic/congestion_control/tcp_receiver.h" |
12 #include "net/quic/crypto/crypto_protocol.h" | 12 #include "net/quic/crypto/crypto_protocol.h" |
13 #include "net/quic/quic_utils.h" | 13 #include "net/quic/quic_utils.h" |
14 #include "net/quic/test_tools/mock_clock.h" | 14 #include "net/quic/test_tools/mock_clock.h" |
15 #include "net/quic/test_tools/quic_config_peer.h" | 15 #include "net/quic/test_tools/quic_config_peer.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
17 | 17 |
18 using std::make_pair; | 18 using std::make_pair; |
19 using std::min; | 19 using std::min; |
20 | 20 |
21 namespace net { | 21 namespace net { |
22 namespace test { | 22 namespace test { |
23 | 23 |
24 const int64 kInitialCongestionWindow = 10; | 24 const int64 kInitialCongestionWindow = 10; |
25 const uint32 kDefaultWindowTCP = kInitialCongestionWindow * kDefaultTCPMSS; | 25 const uint32 kDefaultWindowTCP = kInitialCongestionWindow * kDefaultTCPMSS; |
| 26 const float kRenoBeta = 0.7f; // Reno backoff factor. |
26 | 27 |
27 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. | 28 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. |
28 const QuicPacketCount kDefaultMaxCongestionWindowTCP = 10000; | 29 const QuicPacketCount kDefaultMaxCongestionWindowTCP = 10000; |
29 | 30 |
30 class TcpCubicSenderPeer : public TcpCubicSender { | 31 class TcpCubicSenderPeer : public TcpCubicSender { |
31 public: | 32 public: |
32 TcpCubicSenderPeer(const QuicClock* clock, | 33 TcpCubicSenderPeer(const QuicClock* clock, |
33 bool reno, | 34 bool reno, |
34 QuicPacketCount max_tcp_congestion_window) | 35 QuicPacketCount max_tcp_congestion_window) |
35 : TcpCubicSender( | 36 : TcpCubicSender( |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 SendAvailableSendWindow(); | 258 SendAvailableSendWindow(); |
258 AckNPackets(2); | 259 AckNPackets(2); |
259 } | 260 } |
260 SendAvailableSendWindow(); | 261 SendAvailableSendWindow(); |
261 QuicByteCount expected_send_window = kDefaultWindowTCP + | 262 QuicByteCount expected_send_window = kDefaultWindowTCP + |
262 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 263 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
263 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 264 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
264 | 265 |
265 // Lose a packet to exit slow start. | 266 // Lose a packet to exit slow start. |
266 LoseNPackets(1); | 267 LoseNPackets(1); |
| 268 size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS; |
267 | 269 |
268 // We should now have fallen out of slow start. | 270 // We should now have fallen out of slow start with a reduced window. |
269 // We expect window to be cut in half by Reno. | 271 expected_send_window *= kRenoBeta; |
270 expected_send_window /= 2; | |
271 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 272 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
272 | 273 |
273 // Testing Reno phase. | 274 // Recovery phase. We need to ack every packet in the recovery window before |
274 // We need to ack half of the pending packet before we can send again. | 275 // we exit recovery. |
275 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; | 276 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; |
276 AckNPackets(number_of_packets_in_window); | 277 DVLOG(1) << "number_packets: " << number_of_packets_in_window; |
| 278 AckNPackets(packets_in_recovery_window); |
| 279 SendAvailableSendWindow(); |
277 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 280 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
278 | 281 |
279 // We need to ack every packet in the window before we exit recovery. | 282 // We need to ack an entire window before we increase CWND by 1. |
280 for (size_t i = 0; i < number_of_packets_in_window; ++i) { | 283 AckNPackets(number_of_packets_in_window - 2); |
281 AckNPackets(1); | 284 SendAvailableSendWindow(); |
282 SendAvailableSendWindow(); | 285 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
283 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
284 } | |
285 | 286 |
286 // We need to ack another window before we increase CWND by 1. | 287 // Next ack should increase cwnd by 1. |
287 for (size_t i = 0; i < number_of_packets_in_window - 2; ++i) { | |
288 AckNPackets(1); | |
289 SendAvailableSendWindow(); | |
290 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
291 } | |
292 | |
293 AckNPackets(1); | 288 AckNPackets(1); |
294 expected_send_window += kDefaultTCPMSS; | 289 expected_send_window += kDefaultTCPMSS; |
295 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 290 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
296 | 291 |
297 // Now RTO and ensure slow start gets reset. | 292 // Now RTO and ensure slow start gets reset. |
298 EXPECT_TRUE(sender_->hybrid_slow_start().started()); | 293 EXPECT_TRUE(sender_->hybrid_slow_start().started()); |
299 sender_->OnRetransmissionTimeout(true); | 294 sender_->OnRetransmissionTimeout(true); |
300 EXPECT_FALSE(sender_->hybrid_slow_start().started()); | 295 EXPECT_FALSE(sender_->hybrid_slow_start().started()); |
301 } | 296 } |
302 | 297 |
(...skipping 20 matching lines...) Expand all Loading... |
323 SendAvailableSendWindow(); | 318 SendAvailableSendWindow(); |
324 AckNPackets(2); | 319 AckNPackets(2); |
325 } | 320 } |
326 SendAvailableSendWindow(); | 321 SendAvailableSendWindow(); |
327 QuicByteCount expected_send_window = kDefaultWindowTCP + | 322 QuicByteCount expected_send_window = kDefaultWindowTCP + |
328 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 323 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
329 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 324 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
330 | 325 |
331 LoseNPackets(1); | 326 LoseNPackets(1); |
332 | 327 |
333 // We should now have fallen out of slow start. | 328 // We should now have fallen out of slow start with a reduced window. |
334 // We expect window to be cut in half by Reno. | 329 size_t send_window_before_loss = expected_send_window; |
335 expected_send_window /= 2; | 330 expected_send_window *= kRenoBeta; |
336 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 331 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
337 | 332 |
338 // Testing TCP proportional rate reduction. | 333 // Testing TCP proportional rate reduction. |
339 // We should send one packet for every two received acks over the remaining | 334 // We should send packets paced over the received acks for the remaining |
340 // 18 outstanding packets. | 335 // outstanding packets. The number of packets before we exit recovery is the |
341 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; | 336 // original CWND minus the packet that has been lost and the one which |
342 // The number of packets before we exit recovery is the original CWND minus | 337 // triggered the loss. |
343 // the packet that has been lost and the one which triggered the loss. | 338 size_t remaining_packets_in_recovery = |
344 size_t remaining_packets_in_recovery = number_of_packets_in_window * 2 - 1; | 339 send_window_before_loss / kDefaultTCPMSS - 2; |
345 for (size_t i = 0; i < remaining_packets_in_recovery - 1; i += 2) { | 340 |
346 AckNPackets(2); | 341 for (size_t i = 0; i < remaining_packets_in_recovery; ++i) { |
347 EXPECT_TRUE(sender_->TimeUntilSend( | 342 AckNPackets(1); |
348 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero()); | 343 SendAvailableSendWindow(); |
349 EXPECT_EQ(1, SendAvailableSendWindow()); | |
350 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 344 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
351 } | 345 } |
352 | 346 |
353 // We need to ack another window before we increase CWND by 1. | 347 // We need to ack another window before we increase CWND by 1. |
| 348 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; |
354 for (size_t i = 0; i < number_of_packets_in_window; ++i) { | 349 for (size_t i = 0; i < number_of_packets_in_window; ++i) { |
355 AckNPackets(1); | 350 AckNPackets(1); |
356 EXPECT_EQ(1, SendAvailableSendWindow()); | 351 EXPECT_EQ(1, SendAvailableSendWindow()); |
357 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 352 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
358 } | 353 } |
359 | 354 |
360 AckNPackets(1); | 355 AckNPackets(1); |
361 expected_send_window += kDefaultTCPMSS; | 356 expected_send_window += kDefaultTCPMSS; |
362 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 357 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
363 } | 358 } |
364 | 359 |
365 TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) { | 360 TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) { |
366 sender_->SetNumEmulatedConnections(1); | 361 sender_->SetNumEmulatedConnections(1); |
367 // Test based on the second example in RFC6937, though we also implement | 362 // Test based on the second example in RFC6937, though we also implement |
368 // forward acknowledgements, so the first two incoming acks will trigger | 363 // forward acknowledgements, so the first two incoming acks will trigger |
369 // PRR immediately. | 364 // PRR immediately. |
370 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example. | 365 // Ack 20 packets in 10 acks to raise the CWND to 30. |
371 const int kNumberOfAcks = 5; | 366 const int kNumberOfAcks = 10; |
372 for (int i = 0; i < kNumberOfAcks; ++i) { | 367 for (int i = 0; i < kNumberOfAcks; ++i) { |
373 // Send our full send window. | 368 // Send our full send window. |
374 SendAvailableSendWindow(); | 369 SendAvailableSendWindow(); |
375 AckNPackets(2); | 370 AckNPackets(2); |
376 } | 371 } |
377 SendAvailableSendWindow(); | 372 SendAvailableSendWindow(); |
378 QuicByteCount expected_send_window = kDefaultWindowTCP + | 373 QuicByteCount expected_send_window = kDefaultWindowTCP + |
379 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 374 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
380 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 375 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
381 | 376 |
382 // Ack a packet with a 15 packet gap, losing 13 of them due to FACK. | 377 // Lose one more than the congestion window reduction, so that after loss, |
383 LoseNPackets(13); | 378 // bytes_in_flight is lesser than the congestion window. |
| 379 size_t send_window_after_loss = kRenoBeta * expected_send_window; |
| 380 size_t num_packets_to_lose = |
| 381 (expected_send_window - send_window_after_loss) / kDefaultTCPMSS + 1; |
| 382 LoseNPackets(num_packets_to_lose); |
384 // Immediately after the loss, ensure at least one packet can be sent. | 383 // Immediately after the loss, ensure at least one packet can be sent. |
385 // Losses without subsequent acks can occur with timer based loss detection. | 384 // Losses without subsequent acks can occur with timer based loss detection. |
386 EXPECT_TRUE(sender_->TimeUntilSend( | 385 EXPECT_TRUE(sender_->TimeUntilSend( |
387 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero()); | 386 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero()); |
388 AckNPackets(1); | 387 AckNPackets(1); |
389 | 388 |
390 // We should now have fallen out of slow start. | 389 // We should now have fallen out of slow start with a reduced window. |
391 // We expect window to be cut in half by Reno. | 390 expected_send_window *= kRenoBeta; |
392 expected_send_window /= 2; | |
393 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 391 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
394 | 392 |
395 // Only 2 packets should be allowed to be sent, per PRR-SSRB | 393 // Only 2 packets should be allowed to be sent, per PRR-SSRB |
396 EXPECT_EQ(2, SendAvailableSendWindow()); | 394 EXPECT_EQ(2, SendAvailableSendWindow()); |
397 | 395 |
398 // Ack the next packet, which triggers another loss. | 396 // Ack the next packet, which triggers another loss. |
399 LoseNPackets(1); | 397 LoseNPackets(1); |
400 AckNPackets(1); | 398 AckNPackets(1); |
401 | 399 |
402 // Send 2 packets to simulate PRR-SSRB. | 400 // Send 2 packets to simulate PRR-SSRB. |
403 EXPECT_EQ(2, SendAvailableSendWindow()); | 401 EXPECT_EQ(2, SendAvailableSendWindow()); |
404 | 402 |
405 // Ack the next packet, which triggers another loss. | 403 // Ack the next packet, which triggers another loss. |
406 LoseNPackets(1); | 404 LoseNPackets(1); |
407 AckNPackets(1); | 405 AckNPackets(1); |
408 | 406 |
409 // Send 2 packets to simulate PRR-SSRB. | 407 // Send 2 packets to simulate PRR-SSRB. |
410 EXPECT_EQ(2, SendAvailableSendWindow()); | 408 EXPECT_EQ(2, SendAvailableSendWindow()); |
411 | 409 |
412 AckNPackets(1); | |
413 EXPECT_EQ(2, SendAvailableSendWindow()); | |
414 | |
415 AckNPackets(1); | |
416 EXPECT_EQ(2, SendAvailableSendWindow()); | |
417 | |
418 // The window should not have changed. | |
419 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
420 | |
421 // Exit recovery and return to sending at the new rate. | 410 // Exit recovery and return to sending at the new rate. |
422 for (int i = 0; i < kNumberOfAcks; ++i) { | 411 for (int i = 0; i < kNumberOfAcks; ++i) { |
423 AckNPackets(1); | 412 AckNPackets(1); |
424 EXPECT_EQ(1, SendAvailableSendWindow()); | 413 EXPECT_EQ(1, SendAvailableSendWindow()); |
425 } | 414 } |
426 } | 415 } |
427 | 416 |
428 TEST_F(TcpCubicSenderTest, RTOCongestionWindowAndRevert) { | 417 TEST_F(TcpCubicSenderTest, RTOCongestionWindowAndRevert) { |
429 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 418 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
430 EXPECT_EQ(10000u, sender_->slowstart_threshold()); | 419 EXPECT_EQ(10000u, sender_->slowstart_threshold()); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 SendAvailableSendWindow(); | 591 SendAvailableSendWindow(); |
603 AckNPackets(2); | 592 AckNPackets(2); |
604 } | 593 } |
605 SendAvailableSendWindow(); | 594 SendAvailableSendWindow(); |
606 QuicByteCount expected_send_window = kDefaultWindowTCP + | 595 QuicByteCount expected_send_window = kDefaultWindowTCP + |
607 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 596 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
608 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 597 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
609 | 598 |
610 LoseNPackets(1); | 599 LoseNPackets(1); |
611 | 600 |
612 // We should now have fallen out of slow start, and window should be cut in | 601 // We should now have fallen out of slow start with a reduced window. |
613 // half by Reno. New cwnd should be 10. | 602 expected_send_window *= kRenoBeta; |
614 expected_send_window /= 2; | |
615 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 603 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
616 | 604 |
617 // No congestion window growth should occur in recovery phase, i.e., until the | 605 // No congestion window growth should occur in recovery phase, i.e., until the |
618 // currently outstanding 20 packets are acked. | 606 // currently outstanding 20 packets are acked. |
619 for (int i = 0; i < 10; ++i) { | 607 for (int i = 0; i < 10; ++i) { |
620 // Send our full send window. | 608 // Send our full send window. |
621 SendAvailableSendWindow(); | 609 SendAvailableSendWindow(); |
622 EXPECT_TRUE(sender_->InRecovery()); | 610 EXPECT_TRUE(sender_->InRecovery()); |
623 AckNPackets(2); | 611 AckNPackets(2); |
624 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 612 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
625 } | 613 } |
626 EXPECT_FALSE(sender_->InRecovery()); | 614 EXPECT_FALSE(sender_->InRecovery()); |
627 | 615 |
628 // Out of recovery now. Congestion window should not grow for half an RTT. | 616 // Out of recovery now. Congestion window should not grow for half an RTT. |
| 617 size_t packets_in_send_window = expected_send_window / kDefaultTCPMSS; |
| 618 SendAvailableSendWindow(); |
| 619 AckNPackets(packets_in_send_window / 2 - 2); |
| 620 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 621 |
| 622 // Next ack should increase congestion window by 1MSS. |
629 SendAvailableSendWindow(); | 623 SendAvailableSendWindow(); |
630 AckNPackets(2); | 624 AckNPackets(2); |
| 625 expected_send_window += kDefaultTCPMSS; |
| 626 packets_in_send_window += 1; |
631 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 627 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
632 | 628 |
633 // Next ack will be the 5th and should increase congestion window by 1MSS. | 629 // Congestion window should remain steady again for half an RTT. |
| 630 SendAvailableSendWindow(); |
| 631 AckNPackets(packets_in_send_window / 2 - 1); |
| 632 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 633 |
| 634 // Next ack should cause congestion window to grow by 1MSS. |
| 635 SendAvailableSendWindow(); |
634 AckNPackets(2); | 636 AckNPackets(2); |
635 expected_send_window += kDefaultTCPMSS; | 637 expected_send_window += kDefaultTCPMSS; |
636 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 638 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
637 | |
638 for (int i = 0; i < 2; ++i) { | |
639 SendAvailableSendWindow(); | |
640 AckNPackets(2); | |
641 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
642 } | |
643 | |
644 // Next ack should cause congestion window to grow by 1MSS. | |
645 AckNPackets(2); | |
646 expected_send_window += kDefaultTCPMSS; | |
647 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
648 } | 639 } |
649 | 640 |
650 TEST_F(TcpCubicSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) { | 641 TEST_F(TcpCubicSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) { |
651 sender_->SetNumEmulatedConnections(1); | 642 sender_->SetNumEmulatedConnections(1); |
652 // Ack 10 packets in 5 acks to raise the CWND to 20. | 643 // Ack 10 packets in 5 acks to raise the CWND to 20. |
653 const int kNumberOfAcks = 5; | 644 const int kNumberOfAcks = 5; |
654 for (int i = 0; i < kNumberOfAcks; ++i) { | 645 for (int i = 0; i < kNumberOfAcks; ++i) { |
655 // Send our full send window. | 646 // Send our full send window. |
656 SendAvailableSendWindow(); | 647 SendAvailableSendWindow(); |
657 AckNPackets(2); | 648 AckNPackets(2); |
658 } | 649 } |
659 SendAvailableSendWindow(); | 650 SendAvailableSendWindow(); |
660 QuicByteCount expected_send_window = kDefaultWindowTCP + | 651 QuicByteCount expected_send_window = kDefaultWindowTCP + |
661 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 652 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
662 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 653 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
663 | 654 |
664 LoseNPackets(1); | 655 LoseNPackets(1); |
665 | 656 |
666 // We should now have fallen out of slow start, and window should be cut in | 657 // We should now have fallen out of slow start with a reduced window. |
667 // half by Reno. New cwnd should be 10. | 658 expected_send_window *= kRenoBeta; |
668 expected_send_window /= 2; | |
669 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 659 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
670 | 660 |
671 // No congestion window growth should occur in recovery phase, i.e., until the | 661 // No congestion window growth should occur in recovery phase, i.e., until the |
672 // currently outstanding 20 packets are acked. | 662 // currently outstanding 20 packets are acked. |
673 for (int i = 0; i < 10; ++i) { | 663 for (int i = 0; i < 10; ++i) { |
674 // Send our full send window. | 664 // Send our full send window. |
675 SendAvailableSendWindow(); | 665 SendAvailableSendWindow(); |
676 EXPECT_TRUE(sender_->InRecovery()); | 666 EXPECT_TRUE(sender_->InRecovery()); |
677 AckNPackets(2); | 667 AckNPackets(2); |
678 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 668 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
679 } | 669 } |
680 EXPECT_FALSE(sender_->InRecovery()); | 670 EXPECT_FALSE(sender_->InRecovery()); |
681 | 671 |
682 // Out of recovery now. Congestion window should not grow during RTT. | 672 // Out of recovery now. Congestion window should not grow during RTT. |
683 for (int i = 0; i < 4; ++i) { | 673 for (uint64 i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) { |
684 // Send our full send window. | 674 // Send our full send window. |
685 SendAvailableSendWindow(); | 675 SendAvailableSendWindow(); |
686 AckNPackets(2); | 676 AckNPackets(2); |
687 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 677 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
688 } | 678 } |
689 | 679 |
690 // Next ack should cause congestion window to grow by 1MSS. | 680 // Next ack should cause congestion window to grow by 1MSS. |
| 681 SendAvailableSendWindow(); |
691 AckNPackets(2); | 682 AckNPackets(2); |
692 expected_send_window += kDefaultTCPMSS; | 683 expected_send_window += kDefaultTCPMSS; |
693 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 684 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
694 } | 685 } |
695 | 686 |
696 } // namespace test | 687 } // namespace test |
697 } // namespace net | 688 } // namespace net |
OLD | NEW |