| 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 "base/logging.h" | 5 #include "base/logging.h" |
| 6 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
| 7 #include "net/quic/congestion_control/tcp_cubic_sender.h" | 7 #include "net/quic/congestion_control/tcp_cubic_sender.h" |
| 8 #include "net/quic/congestion_control/tcp_receiver.h" | 8 #include "net/quic/congestion_control/tcp_receiver.h" |
| 9 #include "net/quic/test_tools/mock_clock.h" | 9 #include "net/quic/test_tools/mock_clock.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 } | 22 } |
| 23 using TcpCubicSender::AvailableCongestionWindow; | 23 using TcpCubicSender::AvailableCongestionWindow; |
| 24 using TcpCubicSender::CongestionWindow; | 24 using TcpCubicSender::CongestionWindow; |
| 25 }; | 25 }; |
| 26 | 26 |
| 27 class TcpCubicSenderTest : public ::testing::Test { | 27 class TcpCubicSenderTest : public ::testing::Test { |
| 28 protected: | 28 protected: |
| 29 TcpCubicSenderTest() | 29 TcpCubicSenderTest() |
| 30 : rtt_(QuicTime::Delta::FromMilliseconds(60)), | 30 : rtt_(QuicTime::Delta::FromMilliseconds(60)), |
| 31 one_ms_(QuicTime::Delta::FromMilliseconds(1)), | 31 one_ms_(QuicTime::Delta::FromMilliseconds(1)), |
| 32 fake_bandwidth_(QuicBandwidth::Zero()), | |
| 33 sender_(new TcpCubicSenderPeer(&clock_, true)), | 32 sender_(new TcpCubicSenderPeer(&clock_, true)), |
| 34 receiver_(new TcpReceiver()), | 33 receiver_(new TcpReceiver()), |
| 35 sequence_number_(1), | 34 sequence_number_(1), |
| 36 acked_sequence_number_(0) { | 35 acked_sequence_number_(0) { |
| 37 } | 36 } |
| 38 void SendAvailableCongestionWindow() { | 37 void SendAvailableCongestionWindow() { |
| 39 QuicByteCount bytes_to_send = sender_->AvailableCongestionWindow(); | 38 QuicByteCount bytes_to_send = sender_->AvailableCongestionWindow(); |
| 40 while (bytes_to_send > 0) { | 39 while (bytes_to_send > 0) { |
| 41 QuicByteCount bytes_in_packet = std::min(kMaxPacketSize, bytes_to_send); | 40 QuicByteCount bytes_in_packet = std::min(kMaxPacketSize, bytes_to_send); |
| 42 sender_->SentPacket(clock_.Now(), sequence_number_++, bytes_in_packet, | 41 sender_->SentPacket(clock_.Now(), sequence_number_++, bytes_in_packet, |
| 43 NOT_RETRANSMISSION); | 42 NOT_RETRANSMISSION); |
| 44 bytes_to_send -= bytes_in_packet; | 43 bytes_to_send -= bytes_in_packet; |
| 45 if (bytes_to_send > 0) { | 44 if (bytes_to_send > 0) { |
| 46 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION, | 45 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION, |
| 47 HAS_RETRANSMITTABLE_DATA).IsZero()); | 46 HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 48 } | 47 } |
| 49 } | 48 } |
| 50 } | 49 } |
| 51 // Normal is that TCP acks every other segment. | 50 // Normal is that TCP acks every other segment. |
| 52 void AckNPackets(int n) { | 51 void AckNPackets(int n) { |
| 53 for (int i = 0; i < n; ++i) { | 52 for (int i = 0; i < n; ++i) { |
| 54 acked_sequence_number_++; | 53 acked_sequence_number_++; |
| 55 sender_->OnIncomingAck(acked_sequence_number_, kMaxPacketSize, rtt_); | 54 sender_->OnIncomingAck(acked_sequence_number_, kMaxPacketSize, rtt_); |
| 56 } | 55 } |
| 57 clock_.AdvanceTime(one_ms_); // 1 millisecond. | 56 clock_.AdvanceTime(one_ms_); // 1 millisecond. |
| 58 } | 57 } |
| 59 | 58 |
| 60 const QuicTime::Delta rtt_; | 59 const QuicTime::Delta rtt_; |
| 61 const QuicTime::Delta one_ms_; | 60 const QuicTime::Delta one_ms_; |
| 62 const QuicBandwidth fake_bandwidth_; | |
| 63 MockClock clock_; | 61 MockClock clock_; |
| 64 SendAlgorithmInterface::SentPacketsMap not_used_; | 62 SendAlgorithmInterface::SentPacketsMap not_used_; |
| 65 scoped_ptr<TcpCubicSenderPeer> sender_; | 63 scoped_ptr<TcpCubicSenderPeer> sender_; |
| 66 scoped_ptr<TcpReceiver> receiver_; | 64 scoped_ptr<TcpReceiver> receiver_; |
| 67 QuicPacketSequenceNumber sequence_number_; | 65 QuicPacketSequenceNumber sequence_number_; |
| 68 QuicPacketSequenceNumber acked_sequence_number_; | 66 QuicPacketSequenceNumber acked_sequence_number_; |
| 69 }; | 67 }; |
| 70 | 68 |
| 71 TEST_F(TcpCubicSenderTest, SimpleSender) { | 69 TEST_F(TcpCubicSenderTest, SimpleSender) { |
| 72 QuicCongestionFeedbackFrame feedback; | 70 QuicCongestionFeedbackFrame feedback; |
| 73 // At startup make sure we are at the default. | 71 // At startup make sure we are at the default. |
| 74 EXPECT_EQ(kDefaultWindowTCP, | 72 EXPECT_EQ(kDefaultWindowTCP, |
| 75 sender_->AvailableCongestionWindow()); | 73 sender_->AvailableCongestionWindow()); |
| 76 // At startup make sure we can send. | 74 // At startup make sure we can send. |
| 77 EXPECT_TRUE(sender_->TimeUntilSend( | 75 EXPECT_TRUE(sender_->TimeUntilSend( |
| 78 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); | 76 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 79 // Get default QuicCongestionFeedbackFrame from receiver. | 77 // Get default QuicCongestionFeedbackFrame from receiver. |
| 80 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 78 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 81 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), | 79 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), |
| 82 fake_bandwidth_, not_used_); | 80 not_used_); |
| 83 // Make sure we can send. | 81 // Make sure we can send. |
| 84 EXPECT_TRUE(sender_->TimeUntilSend( | 82 EXPECT_TRUE(sender_->TimeUntilSend( |
| 85 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); | 83 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 86 // And that window is un-affected. | 84 // And that window is un-affected. |
| 87 EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableCongestionWindow()); | 85 EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableCongestionWindow()); |
| 88 | 86 |
| 89 // A retransmitt should always retun 0. | 87 // A retransmitt should always retun 0. |
| 90 EXPECT_TRUE(sender_->TimeUntilSend( | 88 EXPECT_TRUE(sender_->TimeUntilSend( |
| 91 clock_.Now(), IS_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); | 89 clock_.Now(), IS_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 92 } | 90 } |
| 93 | 91 |
| 94 TEST_F(TcpCubicSenderTest, ExponentialSlowStart) { | 92 TEST_F(TcpCubicSenderTest, ExponentialSlowStart) { |
| 95 const int kNumberOfAck = 20; | 93 const int kNumberOfAck = 20; |
| 96 QuicCongestionFeedbackFrame feedback; | 94 QuicCongestionFeedbackFrame feedback; |
| 97 // At startup make sure we can send. | 95 // At startup make sure we can send. |
| 98 EXPECT_TRUE(sender_->TimeUntilSend( | 96 EXPECT_TRUE(sender_->TimeUntilSend( |
| 99 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); | 97 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 100 // Get default QuicCongestionFeedbackFrame from receiver. | 98 // Get default QuicCongestionFeedbackFrame from receiver. |
| 101 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 99 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 102 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), | 100 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), |
| 103 fake_bandwidth_, not_used_); | 101 not_used_); |
| 104 // Make sure we can send. | 102 // Make sure we can send. |
| 105 EXPECT_TRUE(sender_->TimeUntilSend( | 103 EXPECT_TRUE(sender_->TimeUntilSend( |
| 106 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); | 104 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 107 | 105 |
| 108 for (int n = 0; n < kNumberOfAck; ++n) { | 106 for (int n = 0; n < kNumberOfAck; ++n) { |
| 109 // Send our full congestion window. | 107 // Send our full congestion window. |
| 110 SendAvailableCongestionWindow(); | 108 SendAvailableCongestionWindow(); |
| 111 AckNPackets(2); | 109 AckNPackets(2); |
| 112 } | 110 } |
| 113 QuicByteCount bytes_to_send = sender_->CongestionWindow(); | 111 QuicByteCount bytes_to_send = sender_->CongestionWindow(); |
| 114 EXPECT_EQ(kDefaultWindowTCP + kMaxPacketSize * 2 * kNumberOfAck, | 112 EXPECT_EQ(kDefaultWindowTCP + kMaxPacketSize * 2 * kNumberOfAck, |
| 115 bytes_to_send); | 113 bytes_to_send); |
| 116 } | 114 } |
| 117 | 115 |
| 118 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { | 116 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { |
| 119 // Make sure that we fall out of slow start when we send ACK train longer | 117 // Make sure that we fall out of slow start when we send ACK train longer |
| 120 // than half the RTT, in this test case 30ms, which is more than 30 calls to | 118 // than half the RTT, in this test case 30ms, which is more than 30 calls to |
| 121 // Ack2Packets in one round. | 119 // Ack2Packets in one round. |
| 122 // Since we start at 10 packet first round will be 5 second round 10 etc | 120 // Since we start at 10 packet first round will be 5 second round 10 etc |
| 123 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 | 121 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 |
| 124 const int kNumberOfAck = 65; | 122 const int kNumberOfAck = 65; |
| 125 QuicCongestionFeedbackFrame feedback; | 123 QuicCongestionFeedbackFrame feedback; |
| 126 // At startup make sure we can send. | 124 // At startup make sure we can send. |
| 127 EXPECT_TRUE(sender_->TimeUntilSend( | 125 EXPECT_TRUE(sender_->TimeUntilSend( |
| 128 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); | 126 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 129 // Get default QuicCongestionFeedbackFrame from receiver. | 127 // Get default QuicCongestionFeedbackFrame from receiver. |
| 130 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 128 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 131 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), | 129 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), |
| 132 fake_bandwidth_, not_used_); | 130 not_used_); |
| 133 // Make sure we can send. | 131 // Make sure we can send. |
| 134 EXPECT_TRUE(sender_->TimeUntilSend( | 132 EXPECT_TRUE(sender_->TimeUntilSend( |
| 135 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); | 133 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 136 | 134 |
| 137 for (int n = 0; n < kNumberOfAck; ++n) { | 135 for (int n = 0; n < kNumberOfAck; ++n) { |
| 138 // Send our full congestion window. | 136 // Send our full congestion window. |
| 139 SendAvailableCongestionWindow(); | 137 SendAvailableCongestionWindow(); |
| 140 AckNPackets(2); | 138 AckNPackets(2); |
| 141 } | 139 } |
| 142 QuicByteCount expected_congestion_window = kDefaultWindowTCP + | 140 QuicByteCount expected_congestion_window = kDefaultWindowTCP + |
| (...skipping 22 matching lines...) Expand all Loading... |
| 165 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { | 163 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { |
| 166 // Make sure that we fall out of slow start when we encounter a packet loss. | 164 // Make sure that we fall out of slow start when we encounter a packet loss. |
| 167 const int kNumberOfAck = 10; | 165 const int kNumberOfAck = 10; |
| 168 QuicCongestionFeedbackFrame feedback; | 166 QuicCongestionFeedbackFrame feedback; |
| 169 // At startup make sure we can send. | 167 // At startup make sure we can send. |
| 170 EXPECT_TRUE(sender_->TimeUntilSend( | 168 EXPECT_TRUE(sender_->TimeUntilSend( |
| 171 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); | 169 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 172 // Get default QuicCongestionFeedbackFrame from receiver. | 170 // Get default QuicCongestionFeedbackFrame from receiver. |
| 173 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 171 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 174 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), | 172 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), |
| 175 fake_bandwidth_, not_used_); | 173 not_used_); |
| 176 // Make sure we can send. | 174 // Make sure we can send. |
| 177 EXPECT_TRUE(sender_->TimeUntilSend( | 175 EXPECT_TRUE(sender_->TimeUntilSend( |
| 178 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); | 176 clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 179 | 177 |
| 180 for (int i = 0; i < kNumberOfAck; ++i) { | 178 for (int i = 0; i < kNumberOfAck; ++i) { |
| 181 // Send our full congestion window. | 179 // Send our full congestion window. |
| 182 SendAvailableCongestionWindow(); | 180 SendAvailableCongestionWindow(); |
| 183 AckNPackets(2); | 181 AckNPackets(2); |
| 184 } | 182 } |
| 185 SendAvailableCongestionWindow(); | 183 SendAvailableCongestionWindow(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); | 216 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); |
| 219 } | 217 } |
| 220 SendAvailableCongestionWindow(); | 218 SendAvailableCongestionWindow(); |
| 221 AckNPackets(1); | 219 AckNPackets(1); |
| 222 expected_congestion_window += kMaxPacketSize; | 220 expected_congestion_window += kMaxPacketSize; |
| 223 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); | 221 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); |
| 224 } | 222 } |
| 225 | 223 |
| 226 } // namespace test | 224 } // namespace test |
| 227 } // namespace net | 225 } // namespace net |
| OLD | NEW |