| 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()), |
| 32 sender_(new TcpCubicSenderPeer(&clock_, true)), | 33 sender_(new TcpCubicSenderPeer(&clock_, true)), |
| 33 receiver_(new TcpReceiver()), | 34 receiver_(new TcpReceiver()), |
| 34 sequence_number_(1), | 35 sequence_number_(1), |
| 35 acked_sequence_number_(0) { | 36 acked_sequence_number_(0) { |
| 36 } | 37 } |
| 37 void SendAvailableCongestionWindow() { | 38 void SendAvailableCongestionWindow() { |
| 38 QuicByteCount bytes_to_send = sender_->AvailableCongestionWindow(); | 39 QuicByteCount bytes_to_send = sender_->AvailableCongestionWindow(); |
| 39 while (bytes_to_send > 0) { | 40 while (bytes_to_send > 0) { |
| 40 QuicByteCount bytes_in_packet = std::min(kMaxPacketSize, bytes_to_send); | 41 QuicByteCount bytes_in_packet = std::min(kMaxPacketSize, bytes_to_send); |
| 41 sender_->SentPacket(sequence_number_++, bytes_in_packet, false); | 42 sender_->SentPacket(clock_.Now(), sequence_number_++, bytes_in_packet, |
| 43 false); |
| 42 bytes_to_send -= bytes_in_packet; | 44 bytes_to_send -= bytes_in_packet; |
| 43 if (bytes_to_send > 0) { | 45 if (bytes_to_send > 0) { |
| 44 EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero()); | 46 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), false).IsZero()); |
| 45 } | 47 } |
| 46 } | 48 } |
| 47 } | 49 } |
| 48 // Normal is that TCP acks every other segment. | 50 // Normal is that TCP acks every other segment. |
| 49 void AckNPackets(int n) { | 51 void AckNPackets(int n) { |
| 50 for (int i = 0; i < n; ++i) { | 52 for (int i = 0; i < n; ++i) { |
| 51 acked_sequence_number_++; | 53 acked_sequence_number_++; |
| 52 sender_->OnIncomingAck(acked_sequence_number_, kMaxPacketSize, rtt_); | 54 sender_->OnIncomingAck(acked_sequence_number_, kMaxPacketSize, rtt_); |
| 53 } | 55 } |
| 54 clock_.AdvanceTime(one_ms_); // 1 millisecond. | 56 clock_.AdvanceTime(one_ms_); // 1 millisecond. |
| 55 } | 57 } |
| 56 | 58 |
| 57 const QuicTime::Delta rtt_; | 59 const QuicTime::Delta rtt_; |
| 58 const QuicTime::Delta one_ms_; | 60 const QuicTime::Delta one_ms_; |
| 61 const QuicBandwidth fake_bandwidth_; |
| 59 MockClock clock_; | 62 MockClock clock_; |
| 60 SendAlgorithmInterface::SentPacketsMap not_used_; | 63 SendAlgorithmInterface::SentPacketsMap not_used_; |
| 61 scoped_ptr<TcpCubicSenderPeer> sender_; | 64 scoped_ptr<TcpCubicSenderPeer> sender_; |
| 62 scoped_ptr<TcpReceiver> receiver_; | 65 scoped_ptr<TcpReceiver> receiver_; |
| 63 QuicPacketSequenceNumber sequence_number_; | 66 QuicPacketSequenceNumber sequence_number_; |
| 64 QuicPacketSequenceNumber acked_sequence_number_; | 67 QuicPacketSequenceNumber acked_sequence_number_; |
| 65 }; | 68 }; |
| 66 | 69 |
| 67 TEST_F(TcpCubicSenderTest, SimpleSender) { | 70 TEST_F(TcpCubicSenderTest, SimpleSender) { |
| 68 QuicCongestionFeedbackFrame feedback; | 71 QuicCongestionFeedbackFrame feedback; |
| 69 // At startup make sure we are at the default. | 72 // At startup make sure we are at the default. |
| 70 EXPECT_EQ(kDefaultWindowTCP, | 73 EXPECT_EQ(kDefaultWindowTCP, |
| 71 sender_->AvailableCongestionWindow()); | 74 sender_->AvailableCongestionWindow()); |
| 72 // At startup make sure we can send. | 75 // At startup make sure we can send. |
| 73 EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero()); | 76 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), false).IsZero()); |
| 74 // Get default QuicCongestionFeedbackFrame from receiver. | 77 // Get default QuicCongestionFeedbackFrame from receiver. |
| 75 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 78 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 76 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, not_used_); | 79 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), |
| 80 fake_bandwidth_, not_used_); |
| 77 // Make sure we can send. | 81 // Make sure we can send. |
| 78 EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero()); | 82 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), false).IsZero()); |
| 79 // And that window is un-affected. | 83 // And that window is un-affected. |
| 80 EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableCongestionWindow()); | 84 EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableCongestionWindow()); |
| 81 | 85 |
| 82 // A retransmitt should always retun 0. | 86 // A retransmitt should always retun 0. |
| 83 EXPECT_TRUE(sender_->TimeUntilSend(true).IsZero()); | 87 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), true).IsZero()); |
| 84 } | 88 } |
| 85 | 89 |
| 86 TEST_F(TcpCubicSenderTest, ExponentialSlowStart) { | 90 TEST_F(TcpCubicSenderTest, ExponentialSlowStart) { |
| 87 const int kNumberOfAck = 20; | 91 const int kNumberOfAck = 20; |
| 88 QuicCongestionFeedbackFrame feedback; | 92 QuicCongestionFeedbackFrame feedback; |
| 89 // At startup make sure we can send. | 93 // At startup make sure we can send. |
| 90 EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero()); | 94 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), false).IsZero()); |
| 91 // Get default QuicCongestionFeedbackFrame from receiver. | 95 // Get default QuicCongestionFeedbackFrame from receiver. |
| 92 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 96 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 93 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, not_used_); | 97 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), |
| 98 fake_bandwidth_, not_used_); |
| 94 // Make sure we can send. | 99 // Make sure we can send. |
| 95 EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero()); | 100 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), false).IsZero()); |
| 96 | 101 |
| 97 for (int n = 0; n < kNumberOfAck; ++n) { | 102 for (int n = 0; n < kNumberOfAck; ++n) { |
| 98 // Send our full congestion window. | 103 // Send our full congestion window. |
| 99 SendAvailableCongestionWindow(); | 104 SendAvailableCongestionWindow(); |
| 100 AckNPackets(2); | 105 AckNPackets(2); |
| 101 } | 106 } |
| 102 QuicByteCount bytes_to_send = sender_->CongestionWindow(); | 107 QuicByteCount bytes_to_send = sender_->CongestionWindow(); |
| 103 EXPECT_EQ(kDefaultWindowTCP + kMaxPacketSize * 2 * kNumberOfAck, | 108 EXPECT_EQ(kDefaultWindowTCP + kMaxPacketSize * 2 * kNumberOfAck, |
| 104 bytes_to_send); | 109 bytes_to_send); |
| 105 } | 110 } |
| 106 | 111 |
| 107 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { | 112 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { |
| 108 // Make sure that we fall out of slow start when we send ACK train longer | 113 // Make sure that we fall out of slow start when we send ACK train longer |
| 109 // than half the RTT, in this test case 30ms, which is more than 30 calls to | 114 // than half the RTT, in this test case 30ms, which is more than 30 calls to |
| 110 // Ack2Packets in one round. | 115 // Ack2Packets in one round. |
| 111 // Since we start at 10 packet first round will be 5 second round 10 etc | 116 // Since we start at 10 packet first round will be 5 second round 10 etc |
| 112 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 | 117 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 |
| 113 const int kNumberOfAck = 65; | 118 const int kNumberOfAck = 65; |
| 114 QuicCongestionFeedbackFrame feedback; | 119 QuicCongestionFeedbackFrame feedback; |
| 115 // At startup make sure we can send. | 120 // At startup make sure we can send. |
| 116 EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero()); | 121 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), false).IsZero()); |
| 117 // Get default QuicCongestionFeedbackFrame from receiver. | 122 // Get default QuicCongestionFeedbackFrame from receiver. |
| 118 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 123 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 119 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, not_used_); | 124 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), |
| 125 fake_bandwidth_, not_used_); |
| 120 // Make sure we can send. | 126 // Make sure we can send. |
| 121 EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero()); | 127 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), false).IsZero()); |
| 122 | 128 |
| 123 for (int n = 0; n < kNumberOfAck; ++n) { | 129 for (int n = 0; n < kNumberOfAck; ++n) { |
| 124 // Send our full congestion window. | 130 // Send our full congestion window. |
| 125 SendAvailableCongestionWindow(); | 131 SendAvailableCongestionWindow(); |
| 126 AckNPackets(2); | 132 AckNPackets(2); |
| 127 } | 133 } |
| 128 QuicByteCount expected_congestion_window = kDefaultWindowTCP + | 134 QuicByteCount expected_congestion_window = kDefaultWindowTCP + |
| 129 (kMaxPacketSize * 2 * kNumberOfAck); | 135 (kMaxPacketSize * 2 * kNumberOfAck); |
| 130 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); | 136 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); |
| 131 // We should now have fallen out of slow start. | 137 // We should now have fallen out of slow start. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 146 AckNPackets(2); | 152 AckNPackets(2); |
| 147 expected_congestion_window += kMaxPacketSize; | 153 expected_congestion_window += kMaxPacketSize; |
| 148 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); | 154 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); |
| 149 } | 155 } |
| 150 | 156 |
| 151 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { | 157 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { |
| 152 // Make sure that we fall out of slow start when we encounter a packet loss. | 158 // Make sure that we fall out of slow start when we encounter a packet loss. |
| 153 const int kNumberOfAck = 10; | 159 const int kNumberOfAck = 10; |
| 154 QuicCongestionFeedbackFrame feedback; | 160 QuicCongestionFeedbackFrame feedback; |
| 155 // At startup make sure we can send. | 161 // At startup make sure we can send. |
| 156 EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero()); | 162 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), false).IsZero()); |
| 157 // Get default QuicCongestionFeedbackFrame from receiver. | 163 // Get default QuicCongestionFeedbackFrame from receiver. |
| 158 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 164 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 159 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, not_used_); | 165 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), |
| 166 fake_bandwidth_, not_used_); |
| 160 // Make sure we can send. | 167 // Make sure we can send. |
| 161 EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero()); | 168 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), false).IsZero()); |
| 162 | 169 |
| 163 for (int i = 0; i < kNumberOfAck; ++i) { | 170 for (int i = 0; i < kNumberOfAck; ++i) { |
| 164 // Send our full congestion window. | 171 // Send our full congestion window. |
| 165 SendAvailableCongestionWindow(); | 172 SendAvailableCongestionWindow(); |
| 166 AckNPackets(2); | 173 AckNPackets(2); |
| 167 } | 174 } |
| 168 SendAvailableCongestionWindow(); | 175 SendAvailableCongestionWindow(); |
| 169 QuicByteCount expected_congestion_window = kDefaultWindowTCP + | 176 QuicByteCount expected_congestion_window = kDefaultWindowTCP + |
| 170 (kMaxPacketSize * 2 * kNumberOfAck); | 177 (kMaxPacketSize * 2 * kNumberOfAck); |
| 171 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); | 178 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); |
| 172 | 179 |
| 173 sender_->OnIncomingLoss(1); | 180 sender_->OnIncomingLoss(clock_.Now()); |
| 174 | 181 |
| 175 // Make sure that we should not send right now. | 182 // Make sure that we should not send right now. |
| 176 EXPECT_TRUE(sender_->TimeUntilSend(false).IsInfinite()); | 183 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), false).IsInfinite()); |
| 177 | 184 |
| 178 // We should now have fallen out of slow start. | 185 // We should now have fallen out of slow start. |
| 179 // We expect window to be cut in half. | 186 // We expect window to be cut in half. |
| 180 expected_congestion_window /= 2; | 187 expected_congestion_window /= 2; |
| 181 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); | 188 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); |
| 182 | 189 |
| 183 // Testing Reno phase. | 190 // Testing Reno phase. |
| 184 // We need to ack half of the pending packet before we can send agin. | 191 // We need to ack half of the pending packet before we can send agin. |
| 185 int number_of_packets_in_window = expected_congestion_window / kMaxPacketSize; | 192 int number_of_packets_in_window = expected_congestion_window / kMaxPacketSize; |
| 186 AckNPackets(number_of_packets_in_window); | 193 AckNPackets(number_of_packets_in_window); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 200 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); | 207 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); |
| 201 } | 208 } |
| 202 SendAvailableCongestionWindow(); | 209 SendAvailableCongestionWindow(); |
| 203 AckNPackets(1); | 210 AckNPackets(1); |
| 204 expected_congestion_window += kMaxPacketSize; | 211 expected_congestion_window += kMaxPacketSize; |
| 205 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); | 212 EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); |
| 206 } | 213 } |
| 207 | 214 |
| 208 } // namespace test | 215 } // namespace test |
| 209 } // namespace net | 216 } // namespace net |
| OLD | NEW |