1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Test of the full congestion control chain. 6 7 #include "base/logging.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "net/quic/congestion_control/quic_congestion_manager.h" 10 #include "net/quic/quic_protocol.h" 11 #include "net/quic/test_tools/mock_clock.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 using std::max; 15 16 namespace net { 17 namespace test { 18 19 class QuicCongestionManagerPeer : public QuicCongestionManager { 20 public: 21 explicit QuicCongestionManagerPeer(const QuicClock* clock, 22 CongestionFeedbackType congestion_type) 23 : QuicCongestionManager(clock, congestion_type) { 24 } 25 using QuicCongestionManager::BandwidthEstimate; 26 }; 27 28 class QuicCongestionControlTest : public ::testing::Test { 29 protected: 30 QuicCongestionControlTest() 31 : start_(clock_.ApproximateNow()) { 32 } 33 34 void SetUpCongestionType(CongestionFeedbackType congestion_type) { 35 manager_.reset(new QuicCongestionManagerPeer(&clock_, congestion_type)); 36 } 37 38 MockClock clock_; 39 QuicTime start_; 40 scoped_ptr<QuicCongestionManagerPeer> manager_; 41 }; 42 43 TEST_F(QuicCongestionControlTest, FixedRateSenderAPI) { 44 SetUpCongestionType(kFixRate); 45 QuicCongestionFeedbackFrame congestion_feedback; 46 congestion_feedback.type = kFixRate; 47 congestion_feedback.fix_rate.bitrate = QuicBandwidth::FromKBytesPerSecond(30); 48 manager_->OnIncomingQuicCongestionFeedbackFrame(congestion_feedback, 49 clock_.Now()); 50 EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(), 51 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 52 manager_->SentPacket(1, clock_.Now(), kMaxPacketSize, NOT_RETRANSMISSION); 53 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40), 54 manager_->TimeUntilSend(clock_.Now(), 55 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)); 56 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(35)); 57 EXPECT_EQ(QuicTime::Delta::Infinite(), 58 manager_->TimeUntilSend(clock_.Now(), 59 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)); 60 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5)); 61 EXPECT_EQ(QuicTime::Delta::Infinite(), 62 manager_->TimeUntilSend(clock_.Now(), 63 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)); 64 } 65 66 TEST_F(QuicCongestionControlTest, FixedRatePacing) { 67 SetUpCongestionType(kFixRate); 68 QuicAckFrame ack; 69 ack.received_info.largest_observed = 0; 70 manager_->OnIncomingAckFrame(ack, clock_.Now()); 71 72 QuicCongestionFeedbackFrame feedback; 73 feedback.type = kFixRate; 74 feedback.fix_rate.bitrate = QuicBandwidth::FromKBytesPerSecond(100); 75 manager_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); 76 77 QuicTime acc_advance_time(QuicTime::Zero()); 78 for (QuicPacketSequenceNumber i = 1; i <= 100; ++i) { 79 EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(), 80 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 81 manager_->SentPacket(i, clock_.Now(), kMaxPacketSize, NOT_RETRANSMISSION); 82 QuicTime::Delta advance_time = manager_->TimeUntilSend(clock_.Now(), 83 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE); 84 clock_.AdvanceTime(advance_time); 85 acc_advance_time = acc_advance_time.Add(advance_time); 86 // Ack the packet we sent. 87 ack.received_info.largest_observed = max( 88 i, ack.received_info.largest_observed); 89 manager_->OnIncomingAckFrame(ack, clock_.Now()); 90 } 91 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1200), 92 acc_advance_time.Subtract(start_)); 93 } 94 95 TEST_F(QuicCongestionControlTest, Pacing) { 96 SetUpCongestionType(kFixRate); 97 QuicAckFrame ack; 98 ack.received_info.largest_observed = 0; 99 manager_->OnIncomingAckFrame(ack, clock_.Now()); 100 101 QuicCongestionFeedbackFrame feedback; 102 feedback.type = kFixRate; 103 // Test a high bitrate (8Mbit/s) to trigger pacing. 104 feedback.fix_rate.bitrate = QuicBandwidth::FromKBytesPerSecond(1000); 105 manager_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); 106 107 QuicTime acc_advance_time(QuicTime::Zero()); 108 for (QuicPacketSequenceNumber i = 1; i <= 100;) { 109 EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(), 110 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 111 manager_->SentPacket(i++, clock_.Now(), kMaxPacketSize, NOT_RETRANSMISSION); 112 EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(), 113 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 114 manager_->SentPacket(i++, clock_.Now(), kMaxPacketSize, NOT_RETRANSMISSION); 115 QuicTime::Delta advance_time = manager_->TimeUntilSend(clock_.Now(), 116 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE); 117 clock_.AdvanceTime(advance_time); 118 acc_advance_time = acc_advance_time.Add(advance_time); 119 // Ack the packets we sent. 120 ack.received_info.largest_observed = max( 121 i - 2, ack.received_info.largest_observed); 122 manager_->OnIncomingAckFrame(ack, clock_.Now()); 123 ack.received_info.largest_observed = max( 124 i - 1, ack.received_info.largest_observed); 125 manager_->OnIncomingAckFrame(ack, clock_.Now()); 126 } 127 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(120), 128 acc_advance_time.Subtract(start_)); 129 } 130 131 // TODO(pwestin): add TCP tests. 132 133 // TODO(pwestin): add InterArrival tests. 134 135 } // namespace test 136 } // namespace net 137