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 = kDefaultInitialWindow * kDefaultTCPMSS; | 24 // TODO(ianswett): A number of theses tests were written with the assumption of |
| 25 // an initial CWND of 10. They have carefully calculated values which should be |
| 26 // updated to be based on kInitialCongestionWindowInsecure. |
| 27 const uint32 kInitialCongestionWindowPackets = 10; |
| 28 const uint32 kDefaultWindowTCP = |
| 29 kInitialCongestionWindowPackets * kDefaultTCPMSS; |
25 const float kRenoBeta = 0.7f; // Reno backoff factor. | 30 const float kRenoBeta = 0.7f; // Reno backoff factor. |
26 | 31 |
27 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. | |
28 const QuicPacketCount kDefaultMaxCongestionWindowTCP = 10000; | |
29 | |
30 class TcpCubicSenderPeer : public TcpCubicSender { | 32 class TcpCubicSenderPeer : public TcpCubicSender { |
31 public: | 33 public: |
32 TcpCubicSenderPeer(const QuicClock* clock, | 34 TcpCubicSenderPeer(const QuicClock* clock, |
33 bool reno, | 35 bool reno, |
34 QuicPacketCount max_tcp_congestion_window) | 36 QuicPacketCount max_tcp_congestion_window) |
35 : TcpCubicSender( | 37 : TcpCubicSender( |
36 clock, &rtt_stats_, reno, max_tcp_congestion_window, &stats_) { | 38 clock, &rtt_stats_, reno, kInitialCongestionWindowPackets, |
| 39 max_tcp_congestion_window, &stats_) { |
37 } | 40 } |
38 | 41 |
39 QuicPacketCount congestion_window() { | 42 QuicPacketCount congestion_window() { |
40 return congestion_window_; | 43 return congestion_window_; |
41 } | 44 } |
42 | 45 |
43 QuicPacketCount slowstart_threshold() { | 46 QuicPacketCount slowstart_threshold() { |
44 return slowstart_threshold_; | 47 return slowstart_threshold_; |
45 } | 48 } |
46 | 49 |
47 const HybridSlowStart& hybrid_slow_start() const { | 50 const HybridSlowStart& hybrid_slow_start() const { |
48 return hybrid_slow_start_; | 51 return hybrid_slow_start_; |
49 } | 52 } |
50 | 53 |
51 float GetRenoBeta() const { | 54 float GetRenoBeta() const { |
52 return RenoBeta(); | 55 return RenoBeta(); |
53 } | 56 } |
54 | 57 |
55 RttStats rtt_stats_; | 58 RttStats rtt_stats_; |
56 QuicConnectionStats stats_; | 59 QuicConnectionStats stats_; |
57 }; | 60 }; |
58 | 61 |
59 class TcpCubicSenderTest : public ::testing::Test { | 62 class TcpCubicSenderTest : public ::testing::Test { |
60 protected: | 63 protected: |
61 TcpCubicSenderTest() | 64 TcpCubicSenderTest() |
62 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), | 65 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), |
63 sender_(new TcpCubicSenderPeer(&clock_, true, | 66 sender_(new TcpCubicSenderPeer(&clock_, true, |
64 kDefaultMaxCongestionWindowTCP)), | 67 kMaxTcpCongestionWindow)), |
65 receiver_(new TcpReceiver()), | 68 receiver_(new TcpReceiver()), |
66 sequence_number_(1), | 69 sequence_number_(1), |
67 acked_sequence_number_(0), | 70 acked_sequence_number_(0), |
68 bytes_in_flight_(0) { | 71 bytes_in_flight_(0) { |
69 standard_packet_.bytes_sent = kDefaultTCPMSS; | 72 standard_packet_.bytes_sent = kDefaultTCPMSS; |
70 } | 73 } |
71 | 74 |
72 int SendAvailableSendWindow() { | 75 int SendAvailableSendWindow() { |
73 // Send as long as TimeUntilSend returns Zero. | 76 // Send as long as TimeUntilSend returns Zero. |
74 int packets_sent = 0; | 77 int packets_sent = 0; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 const QuicByteCount cwnd = sender_->GetCongestionWindow(); | 205 const QuicByteCount cwnd = sender_->GetCongestionWindow(); |
203 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd); | 206 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd); |
204 EXPECT_FALSE(sender_->HasReliableBandwidthEstimate()); | 207 EXPECT_FALSE(sender_->HasReliableBandwidthEstimate()); |
205 EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta( | 208 EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta( |
206 cwnd, sender_->rtt_stats_.smoothed_rtt()), | 209 cwnd, sender_->rtt_stats_.smoothed_rtt()), |
207 sender_->BandwidthEstimate()); | 210 sender_->BandwidthEstimate()); |
208 } | 211 } |
209 | 212 |
210 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { | 213 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { |
211 sender_->SetNumEmulatedConnections(1); | 214 sender_->SetNumEmulatedConnections(1); |
212 EXPECT_EQ(kDefaultMaxCongestionWindowTCP * kDefaultTCPMSS, | 215 EXPECT_EQ(kMaxTcpCongestionWindow * kDefaultTCPMSS, |
213 sender_->GetSlowStartThreshold()); | 216 sender_->GetSlowStartThreshold()); |
214 | 217 |
215 // Make sure that we fall out of slow start when we send ACK train longer | 218 // Make sure that we fall out of slow start when we send ACK train longer |
216 // than half the RTT, in this test case 30ms, which is more than 30 calls to | 219 // than half the RTT, in this test case 30ms, which is more than 30 calls to |
217 // Ack2Packets in one round. | 220 // Ack2Packets in one round. |
218 // Since we start at 10 packet first round will be 5 second round 10 etc | 221 // Since we start at 10 packet first round will be 5 second round 10 etc |
219 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 | 222 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 |
220 const int kNumberOfAcks = 65; | 223 const int kNumberOfAcks = 65; |
221 for (int i = 0; i < kNumberOfAcks; ++i) { | 224 for (int i = 0; i < kNumberOfAcks; ++i) { |
222 // Send our full send window. | 225 // Send our full send window. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 301 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
299 | 302 |
300 // Now RTO and ensure slow start gets reset. | 303 // Now RTO and ensure slow start gets reset. |
301 EXPECT_TRUE(sender_->hybrid_slow_start().started()); | 304 EXPECT_TRUE(sender_->hybrid_slow_start().started()); |
302 sender_->OnRetransmissionTimeout(true); | 305 sender_->OnRetransmissionTimeout(true); |
303 EXPECT_FALSE(sender_->hybrid_slow_start().started()); | 306 EXPECT_FALSE(sender_->hybrid_slow_start().started()); |
304 } | 307 } |
305 | 308 |
306 TEST_F(TcpCubicSenderTest, NoPRRWhenLessThanOnePacketInFlight) { | 309 TEST_F(TcpCubicSenderTest, NoPRRWhenLessThanOnePacketInFlight) { |
307 SendAvailableSendWindow(); | 310 SendAvailableSendWindow(); |
308 LoseNPackets(kDefaultInitialWindow - 1); | 311 LoseNPackets(kInitialCongestionWindowPackets - 1); |
309 AckNPackets(1); | 312 AckNPackets(1); |
310 // PRR will allow 2 packets for every ack during recovery. | 313 // PRR will allow 2 packets for every ack during recovery. |
311 EXPECT_EQ(2, SendAvailableSendWindow()); | 314 EXPECT_EQ(2, SendAvailableSendWindow()); |
312 // Simulate abandoning all packets by supplying a bytes_in_flight of 0. | 315 // Simulate abandoning all packets by supplying a bytes_in_flight of 0. |
313 // PRR should now allow a packet to be sent, even though prr's state | 316 // PRR should now allow a packet to be sent, even though prr's state |
314 // variables believe it has sent enough packets. | 317 // variables believe it has sent enough packets. |
315 EXPECT_EQ(QuicTime::Delta::Zero(), | 318 EXPECT_EQ(QuicTime::Delta::Zero(), |
316 sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)); | 319 sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)); |
317 } | 320 } |
318 | 321 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 | 420 |
418 // Exit recovery and return to sending at the new rate. | 421 // Exit recovery and return to sending at the new rate. |
419 for (int i = 0; i < kNumberOfAcks; ++i) { | 422 for (int i = 0; i < kNumberOfAcks; ++i) { |
420 AckNPackets(1); | 423 AckNPackets(1); |
421 EXPECT_EQ(1, SendAvailableSendWindow()); | 424 EXPECT_EQ(1, SendAvailableSendWindow()); |
422 } | 425 } |
423 } | 426 } |
424 | 427 |
425 TEST_F(TcpCubicSenderTest, RTOCongestionWindowAndRevert) { | 428 TEST_F(TcpCubicSenderTest, RTOCongestionWindowAndRevert) { |
426 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 429 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
427 EXPECT_EQ(10000u, sender_->slowstart_threshold()); | 430 EXPECT_EQ(kMaxTcpCongestionWindow, sender_->slowstart_threshold()); |
428 | 431 |
429 // Expect the window to decrease to the minimum once the RTO fires | 432 // Expect the window to decrease to the minimum once the RTO fires |
430 // and slow start threshold to be set to 1/2 of the CWND. | 433 // and slow start threshold to be set to 1/2 of the CWND. |
431 sender_->OnRetransmissionTimeout(true); | 434 sender_->OnRetransmissionTimeout(true); |
432 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow()); | 435 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow()); |
433 EXPECT_EQ(5u, sender_->slowstart_threshold()); | 436 EXPECT_EQ(5u, sender_->slowstart_threshold()); |
434 | 437 |
435 // Now repair the RTO and ensure the slowstart threshold reverts. | 438 // Now repair the RTO and ensure the slowstart threshold reverts. |
436 sender_->RevertRetransmissionTimeout(); | 439 sender_->RevertRetransmissionTimeout(); |
437 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 440 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
438 EXPECT_EQ(10000u, sender_->slowstart_threshold()); | 441 EXPECT_EQ(kMaxTcpCongestionWindow, sender_->slowstart_threshold()); |
439 } | 442 } |
440 | 443 |
441 TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) { | 444 TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) { |
442 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 445 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
443 | 446 |
444 // Expect the window to remain unchanged if the RTO fires but no | 447 // Expect the window to remain unchanged if the RTO fires but no |
445 // packets are retransmitted. | 448 // packets are retransmitted. |
446 sender_->OnRetransmissionTimeout(false); | 449 sender_->OnRetransmissionTimeout(false); |
447 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 450 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
448 } | 451 } |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 sequence_number_++, kDefaultTCPMSS, | 570 sequence_number_++, kDefaultTCPMSS, |
568 NO_RETRANSMITTABLE_DATA)); | 571 NO_RETRANSMITTABLE_DATA)); |
569 | 572 |
570 // Send a data packet with retransmittable data, and ensure it is tracked. | 573 // Send a data packet with retransmittable data, and ensure it is tracked. |
571 EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, | 574 EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, |
572 sequence_number_++, kDefaultTCPMSS, | 575 sequence_number_++, kDefaultTCPMSS, |
573 HAS_RETRANSMITTABLE_DATA)); | 576 HAS_RETRANSMITTABLE_DATA)); |
574 } | 577 } |
575 | 578 |
576 TEST_F(TcpCubicSenderTest, ConfigureMaxInitialWindow) { | 579 TEST_F(TcpCubicSenderTest, ConfigureMaxInitialWindow) { |
577 QuicPacketCount congestion_window = sender_->congestion_window(); | |
578 QuicConfig config; | 580 QuicConfig config; |
579 QuicConfigPeer::SetReceivedInitialWindow(&config, 2 * congestion_window); | |
580 | 581 |
581 sender_->SetFromConfig(config, true); | 582 // Verify that kCOPT: kIW10 forces the congestion window to the default of 10. |
582 EXPECT_EQ(2 * congestion_window, sender_->congestion_window()); | |
583 | |
584 // Verify that kCOPT: kIW10 forces the congestion window to the | |
585 // default of 10 regardless of ReceivedInitialWindow. | |
586 QuicTagVector options; | 583 QuicTagVector options; |
587 options.push_back(kIW10); | 584 options.push_back(kIW10); |
588 QuicConfigPeer::SetReceivedConnectionOptions(&config, options); | 585 QuicConfigPeer::SetReceivedConnectionOptions(&config, options); |
589 sender_->SetFromConfig(config, true); | 586 sender_->SetFromConfig(config, |
590 EXPECT_EQ(congestion_window, sender_->congestion_window()); | 587 /* is_server= */ true, |
| 588 /* using_pacing= */ false); |
| 589 EXPECT_EQ(10u, sender_->congestion_window()); |
| 590 } |
| 591 |
| 592 TEST_F(TcpCubicSenderTest, DisableAckTrainDetectionWithPacing) { |
| 593 EXPECT_TRUE(sender_->hybrid_slow_start().ack_train_detection()); |
| 594 |
| 595 QuicConfig config; |
| 596 sender_->SetFromConfig(config, |
| 597 /* is_server= */ true, |
| 598 /* using_pacing= */ true); |
| 599 EXPECT_FALSE(sender_->hybrid_slow_start().ack_train_detection()); |
591 } | 600 } |
592 | 601 |
593 TEST_F(TcpCubicSenderTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) { | 602 TEST_F(TcpCubicSenderTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) { |
594 sender_->SetNumEmulatedConnections(2); | 603 sender_->SetNumEmulatedConnections(2); |
595 // Ack 10 packets in 5 acks to raise the CWND to 20. | 604 // Ack 10 packets in 5 acks to raise the CWND to 20. |
596 const int kNumberOfAcks = 5; | 605 const int kNumberOfAcks = 5; |
597 for (int i = 0; i < kNumberOfAcks; ++i) { | 606 for (int i = 0; i < kNumberOfAcks; ++i) { |
598 // Send our full send window. | 607 // Send our full send window. |
599 SendAvailableSendWindow(); | 608 SendAvailableSendWindow(); |
600 AckNPackets(2); | 609 AckNPackets(2); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 | 696 |
688 // Next ack should cause congestion window to grow by 1MSS. | 697 // Next ack should cause congestion window to grow by 1MSS. |
689 SendAvailableSendWindow(); | 698 SendAvailableSendWindow(); |
690 AckNPackets(2); | 699 AckNPackets(2); |
691 expected_send_window += kDefaultTCPMSS; | 700 expected_send_window += kDefaultTCPMSS; |
692 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 701 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
693 } | 702 } |
694 | 703 |
695 } // namespace test | 704 } // namespace test |
696 } // namespace net | 705 } // namespace net |
OLD | NEW |