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 uint32 kDefaultWindowTCP = 10 * kDefaultTCPMSS; | 24 const int64 kInitialCongestionWindow = 10; |
| 25 const uint32 kDefaultWindowTCP = kInitialCongestionWindow * kDefaultTCPMSS; |
25 | 26 |
26 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. | 27 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. |
27 const QuicTcpCongestionWindow kDefaultMaxCongestionWindowTCP = 10000; | 28 const QuicTcpCongestionWindow kDefaultMaxCongestionWindowTCP = 10000; |
28 | 29 |
29 class TcpCubicSenderPeer : public TcpCubicSender { | 30 class TcpCubicSenderPeer : public TcpCubicSender { |
30 public: | 31 public: |
31 TcpCubicSenderPeer(const QuicClock* clock, | 32 TcpCubicSenderPeer(const QuicClock* clock, |
32 bool reno, | 33 bool reno, |
33 QuicTcpCongestionWindow max_tcp_congestion_window) | 34 QuicTcpCongestionWindow max_tcp_congestion_window) |
34 : TcpCubicSender( | 35 : TcpCubicSender( |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 // Send our full send window. | 194 // Send our full send window. |
194 SendAvailableSendWindow(); | 195 SendAvailableSendWindow(); |
195 AckNPackets(2); | 196 AckNPackets(2); |
196 } | 197 } |
197 QuicByteCount bytes_to_send = sender_->SendWindow(); | 198 QuicByteCount bytes_to_send = sender_->SendWindow(); |
198 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, | 199 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, |
199 bytes_to_send); | 200 bytes_to_send); |
200 } | 201 } |
201 | 202 |
202 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { | 203 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { |
| 204 sender_->SetNumEmulatedConnections(1); |
203 EXPECT_EQ(kDefaultMaxCongestionWindowTCP * kDefaultTCPMSS, | 205 EXPECT_EQ(kDefaultMaxCongestionWindowTCP * kDefaultTCPMSS, |
204 sender_->GetSlowStartThreshold()); | 206 sender_->GetSlowStartThreshold()); |
205 | 207 |
206 // Make sure that we fall out of slow start when we send ACK train longer | 208 // Make sure that we fall out of slow start when we send ACK train longer |
207 // than half the RTT, in this test case 30ms, which is more than 30 calls to | 209 // than half the RTT, in this test case 30ms, which is more than 30 calls to |
208 // Ack2Packets in one round. | 210 // Ack2Packets in one round. |
209 // Since we start at 10 packet first round will be 5 second round 10 etc | 211 // Since we start at 10 packet first round will be 5 second round 10 etc |
210 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 | 212 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 |
211 const int kNumberOfAcks = 65; | 213 const int kNumberOfAcks = 65; |
212 for (int i = 0; i < kNumberOfAcks; ++i) { | 214 for (int i = 0; i < kNumberOfAcks; ++i) { |
(...skipping 30 matching lines...) Expand all Loading... |
243 EXPECT_EQ(expected_send_window / 2 / kDefaultTCPMSS, | 245 EXPECT_EQ(expected_send_window / 2 / kDefaultTCPMSS, |
244 sender_->slowstart_threshold()); | 246 sender_->slowstart_threshold()); |
245 | 247 |
246 // Now revert the RTO and ensure the CWND and slowstart threshold revert. | 248 // Now revert the RTO and ensure the CWND and slowstart threshold revert. |
247 sender_->RevertRetransmissionTimeout(); | 249 sender_->RevertRetransmissionTimeout(); |
248 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 250 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
249 EXPECT_EQ(140u, sender_->slowstart_threshold()); | 251 EXPECT_EQ(140u, sender_->slowstart_threshold()); |
250 } | 252 } |
251 | 253 |
252 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { | 254 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { |
| 255 sender_->SetNumEmulatedConnections(1); |
253 const int kNumberOfAcks = 10; | 256 const int kNumberOfAcks = 10; |
254 for (int i = 0; i < kNumberOfAcks; ++i) { | 257 for (int i = 0; i < kNumberOfAcks; ++i) { |
255 // Send our full send window. | 258 // Send our full send window. |
256 SendAvailableSendWindow(); | 259 SendAvailableSendWindow(); |
257 AckNPackets(2); | 260 AckNPackets(2); |
258 } | 261 } |
259 SendAvailableSendWindow(); | 262 SendAvailableSendWindow(); |
260 QuicByteCount expected_send_window = kDefaultWindowTCP + | 263 QuicByteCount expected_send_window = kDefaultWindowTCP + |
261 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 264 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
262 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 265 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
(...skipping 29 matching lines...) Expand all Loading... |
292 AckNPackets(1); | 295 AckNPackets(1); |
293 expected_send_window += kDefaultTCPMSS; | 296 expected_send_window += kDefaultTCPMSS; |
294 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 297 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
295 | 298 |
296 // Now RTO and ensure slow start gets reset. | 299 // Now RTO and ensure slow start gets reset. |
297 EXPECT_TRUE(sender_->hybrid_slow_start().started()); | 300 EXPECT_TRUE(sender_->hybrid_slow_start().started()); |
298 sender_->OnRetransmissionTimeout(true); | 301 sender_->OnRetransmissionTimeout(true); |
299 EXPECT_FALSE(sender_->hybrid_slow_start().started()); | 302 EXPECT_FALSE(sender_->hybrid_slow_start().started()); |
300 } | 303 } |
301 | 304 |
| 305 TEST_F(TcpCubicSenderTest, NoPRRWhenLessThanOnePacketInFlight) { |
| 306 SendAvailableSendWindow(); |
| 307 LoseNPackets(kInitialCongestionWindow - 1); |
| 308 AckNPackets(1); |
| 309 // PRR will allow 2 packets for every ack during recovery. |
| 310 EXPECT_EQ(2, SendAvailableSendWindow()); |
| 311 // Simulate abandoning all packets by supplying a bytes_in_flight of 0. |
| 312 // PRR should now allow a packet to be sent, even though prr's state |
| 313 // variables believe it has sent enough packets. |
| 314 EXPECT_EQ(QuicTime::Delta::Zero(), |
| 315 sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)); |
| 316 } |
| 317 |
302 TEST_F(TcpCubicSenderTest, SlowStartPacketLossPRR) { | 318 TEST_F(TcpCubicSenderTest, SlowStartPacketLossPRR) { |
| 319 sender_->SetNumEmulatedConnections(1); |
303 // Test based on the first example in RFC6937. | 320 // Test based on the first example in RFC6937. |
304 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example. | 321 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example. |
305 const int kNumberOfAcks = 5; | 322 const int kNumberOfAcks = 5; |
306 for (int i = 0; i < kNumberOfAcks; ++i) { | 323 for (int i = 0; i < kNumberOfAcks; ++i) { |
307 // Send our full send window. | 324 // Send our full send window. |
308 SendAvailableSendWindow(); | 325 SendAvailableSendWindow(); |
309 AckNPackets(2); | 326 AckNPackets(2); |
310 } | 327 } |
311 SendAvailableSendWindow(); | 328 SendAvailableSendWindow(); |
312 QuicByteCount expected_send_window = kDefaultWindowTCP + | 329 QuicByteCount expected_send_window = kDefaultWindowTCP + |
(...skipping 28 matching lines...) Expand all Loading... |
341 EXPECT_EQ(1, SendAvailableSendWindow()); | 358 EXPECT_EQ(1, SendAvailableSendWindow()); |
342 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 359 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
343 } | 360 } |
344 | 361 |
345 AckNPackets(1); | 362 AckNPackets(1); |
346 expected_send_window += kDefaultTCPMSS; | 363 expected_send_window += kDefaultTCPMSS; |
347 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 364 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
348 } | 365 } |
349 | 366 |
350 TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) { | 367 TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) { |
| 368 sender_->SetNumEmulatedConnections(1); |
351 // Test based on the second example in RFC6937, though we also implement | 369 // Test based on the second example in RFC6937, though we also implement |
352 // forward acknowledgements, so the first two incoming acks will trigger | 370 // forward acknowledgements, so the first two incoming acks will trigger |
353 // PRR immediately. | 371 // PRR immediately. |
354 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example. | 372 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example. |
355 const int kNumberOfAcks = 5; | 373 const int kNumberOfAcks = 5; |
356 for (int i = 0; i < kNumberOfAcks; ++i) { | 374 for (int i = 0; i < kNumberOfAcks; ++i) { |
357 // Send our full send window. | 375 // Send our full send window. |
358 SendAvailableSendWindow(); | 376 SendAvailableSendWindow(); |
359 AckNPackets(2); | 377 AckNPackets(2); |
360 } | 378 } |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 | 588 |
571 // Verify that kCOPT: kIW10 forces the congestion window to the | 589 // Verify that kCOPT: kIW10 forces the congestion window to the |
572 // default of 10 regardless of ReceivedInitialWindow. | 590 // default of 10 regardless of ReceivedInitialWindow. |
573 QuicTagVector options; | 591 QuicTagVector options; |
574 options.push_back(kIW10); | 592 options.push_back(kIW10); |
575 QuicConfigPeer::SetReceivedConnectionOptions(&config, options); | 593 QuicConfigPeer::SetReceivedConnectionOptions(&config, options); |
576 sender_->SetFromConfig(config, true); | 594 sender_->SetFromConfig(config, true); |
577 EXPECT_EQ(congestion_window, sender_->congestion_window()); | 595 EXPECT_EQ(congestion_window, sender_->congestion_window()); |
578 } | 596 } |
579 | 597 |
580 TEST_F(TcpCubicSenderTest, CongestionAvoidanceAtEndOfRecovery) { | 598 TEST_F(TcpCubicSenderTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) { |
| 599 sender_->SetNumEmulatedConnections(2); |
581 // Ack 10 packets in 5 acks to raise the CWND to 20. | 600 // Ack 10 packets in 5 acks to raise the CWND to 20. |
582 const int kNumberOfAcks = 5; | 601 const int kNumberOfAcks = 5; |
583 for (int i = 0; i < kNumberOfAcks; ++i) { | 602 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 603 // Send our full send window. |
| 604 SendAvailableSendWindow(); |
| 605 AckNPackets(2); |
| 606 } |
| 607 SendAvailableSendWindow(); |
| 608 QuicByteCount expected_send_window = kDefaultWindowTCP + |
| 609 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
| 610 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 611 |
| 612 LoseNPackets(1); |
| 613 |
| 614 // We should now have fallen out of slow start, and window should be cut in |
| 615 // half by Reno. New cwnd should be 10. |
| 616 expected_send_window /= 2; |
| 617 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 618 |
| 619 // No congestion window growth should occur in recovery phase, i.e., until the |
| 620 // currently outstanding 20 packets are acked. |
| 621 for (int i = 0; i < 10; ++i) { |
| 622 // Send our full send window. |
| 623 SendAvailableSendWindow(); |
| 624 EXPECT_TRUE(sender_->InRecovery()); |
| 625 AckNPackets(2); |
| 626 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 627 } |
| 628 EXPECT_FALSE(sender_->InRecovery()); |
| 629 |
| 630 // Out of recovery now. Congestion window should not grow for half an RTT. |
| 631 SendAvailableSendWindow(); |
| 632 AckNPackets(2); |
| 633 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 634 |
| 635 // Next ack will be the 5th and should increase congestion window by 1MSS. |
| 636 AckNPackets(2); |
| 637 expected_send_window += kDefaultTCPMSS; |
| 638 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 639 |
| 640 for (int i = 0; i < 2; ++i) { |
| 641 SendAvailableSendWindow(); |
| 642 AckNPackets(2); |
| 643 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 644 } |
| 645 |
| 646 // Next ack should cause congestion window to grow by 1MSS. |
| 647 AckNPackets(2); |
| 648 expected_send_window += kDefaultTCPMSS; |
| 649 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 650 } |
| 651 |
| 652 TEST_F(TcpCubicSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) { |
| 653 sender_->SetNumEmulatedConnections(1); |
| 654 // Ack 10 packets in 5 acks to raise the CWND to 20. |
| 655 const int kNumberOfAcks = 5; |
| 656 for (int i = 0; i < kNumberOfAcks; ++i) { |
584 // Send our full send window. | 657 // Send our full send window. |
585 SendAvailableSendWindow(); | 658 SendAvailableSendWindow(); |
586 AckNPackets(2); | 659 AckNPackets(2); |
587 } | 660 } |
588 SendAvailableSendWindow(); | 661 SendAvailableSendWindow(); |
589 QuicByteCount expected_send_window = kDefaultWindowTCP + | 662 QuicByteCount expected_send_window = kDefaultWindowTCP + |
590 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 663 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
591 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 664 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
592 | 665 |
593 LoseNPackets(1); | 666 LoseNPackets(1); |
594 | 667 |
595 // We should now have fallen out of slow start, and window should be cut in | 668 // We should now have fallen out of slow start, and window should be cut in |
596 // half by Reno. New cwnd should be 10. | 669 // half by Reno. New cwnd should be 10. |
597 expected_send_window /= 2; | 670 expected_send_window /= 2; |
598 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 671 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
599 | 672 |
600 // No congestion window growth should occur in recovery phase, i.e., | 673 // No congestion window growth should occur in recovery phase, i.e., |
601 // until the currently outstanding 20 packets are acked. | 674 // until the currently outstanding 20 packets are acked. |
602 for (int i = 0; i < 10; ++i) { | 675 for (int i = 0; i < 10; ++i) { |
603 // Send our full send window. | 676 // Send our full send window. |
604 SendAvailableSendWindow(); | 677 SendAvailableSendWindow(); |
| 678 EXPECT_TRUE(sender_->InRecovery()); |
605 AckNPackets(2); | 679 AckNPackets(2); |
606 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 680 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
607 } | 681 } |
| 682 EXPECT_FALSE(sender_->InRecovery()); |
608 | 683 |
609 // Out of recovery now. Congestion window should not grow during RTT. | 684 // Out of recovery now. Congestion window should not grow during RTT. |
610 for (int i = 0; i < 4; ++i) { | 685 for (int i = 0; i < 4; ++i) { |
611 // Send our full send window. | 686 // Send our full send window. |
612 SendAvailableSendWindow(); | 687 SendAvailableSendWindow(); |
613 AckNPackets(2); | 688 AckNPackets(2); |
614 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 689 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
615 } | 690 } |
616 | 691 |
617 // Next ack should cause congestion window to grow by 1MSS. | 692 // Next ack should cause congestion window to grow by 1MSS. |
618 AckNPackets(2); | 693 AckNPackets(2); |
619 expected_send_window += kDefaultTCPMSS; | 694 expected_send_window += kDefaultTCPMSS; |
620 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 695 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
621 } | 696 } |
622 | 697 |
623 } // namespace test | 698 } // namespace test |
624 } // namespace net | 699 } // namespace net |
OLD | NEW |