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 "net/quic/congestion_control/tcp_cubic_sender.h" | 5 #include "net/quic/congestion_control/tcp_cubic_sender.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "net/quic/congestion_control/rtt_stats.h" | 11 #include "net/quic/congestion_control/rtt_stats.h" |
12 #include "net/quic/crypto/crypto_protocol.h" | 12 #include "net/quic/crypto/crypto_protocol.h" |
13 #include "net/quic/proto/cached_network_parameters.pb.h" | 13 #include "net/quic/proto/cached_network_parameters.pb.h" |
14 #include "net/quic/quic_flags.h" | 14 #include "net/quic/quic_flags.h" |
15 #include "net/quic/quic_protocol.h" | 15 #include "net/quic/quic_protocol.h" |
16 #include "net/quic/quic_utils.h" | 16 #include "net/quic/quic_utils.h" |
17 #include "net/quic/test_tools/mock_clock.h" | 17 #include "net/quic/test_tools/mock_clock.h" |
18 #include "net/quic/test_tools/quic_config_peer.h" | 18 #include "net/quic/test_tools/quic_config_peer.h" |
19 #include "net/quic/test_tools/quic_test_utils.h" | 19 #include "net/quic/test_tools/quic_test_utils.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
21 | 21 |
22 using std::min; | 22 using std::min; |
23 | 23 |
24 namespace net { | 24 namespace net { |
25 namespace test { | 25 namespace test { |
26 | 26 |
27 // TODO(ianswett): A number of theses tests were written with the assumption of | 27 // TODO(ianswett): A number of theses tests were written with the assumption of |
28 // an initial CWND of 10. They have carefully calculated values which should be | 28 // an initial CWND of 10. They have carefully calculated values which should be |
29 // updated to be based on kInitialCongestionWindowInsecure. | 29 // updated to be based on kInitialCongestionWindowInsecure. |
30 const uint32 kInitialCongestionWindowPackets = 10; | 30 const uint32_t kInitialCongestionWindowPackets = 10; |
31 const uint32 kDefaultWindowTCP = | 31 const uint32_t kDefaultWindowTCP = |
32 kInitialCongestionWindowPackets * kDefaultTCPMSS; | 32 kInitialCongestionWindowPackets * kDefaultTCPMSS; |
33 const float kRenoBeta = 0.7f; // Reno backoff factor. | 33 const float kRenoBeta = 0.7f; // Reno backoff factor. |
34 | 34 |
35 class TcpCubicSenderPeer : public TcpCubicSender { | 35 class TcpCubicSenderPeer : public TcpCubicSender { |
36 public: | 36 public: |
37 TcpCubicSenderPeer(const QuicClock* clock, | 37 TcpCubicSenderPeer(const QuicClock* clock, |
38 bool reno, | 38 bool reno, |
39 QuicPacketCount max_tcp_congestion_window) | 39 QuicPacketCount max_tcp_congestion_window) |
40 : TcpCubicSender(clock, | 40 : TcpCubicSender(clock, |
41 &rtt_stats_, | 41 &rtt_stats_, |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) { | 374 TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) { |
375 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 375 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
376 | 376 |
377 // Expect the window to remain unchanged if the RTO fires but no | 377 // Expect the window to remain unchanged if the RTO fires but no |
378 // packets are retransmitted. | 378 // packets are retransmitted. |
379 sender_->OnRetransmissionTimeout(false); | 379 sender_->OnRetransmissionTimeout(false); |
380 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 380 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
381 } | 381 } |
382 | 382 |
383 TEST_F(TcpCubicSenderTest, RetransmissionDelay) { | 383 TEST_F(TcpCubicSenderTest, RetransmissionDelay) { |
384 const int64 kRttMs = 10; | 384 const int64_t kRttMs = 10; |
385 const int64 kDeviationMs = 3; | 385 const int64_t kDeviationMs = 3; |
386 EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay()); | 386 EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay()); |
387 | 387 |
388 sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs), | 388 sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs), |
389 QuicTime::Delta::Zero(), clock_.Now()); | 389 QuicTime::Delta::Zero(), clock_.Now()); |
390 | 390 |
391 // Initial value is to set the median deviation to half of the initial | 391 // Initial value is to set the median deviation to half of the initial |
392 // rtt, the median in then multiplied by a factor of 4 and finally the | 392 // rtt, the median in then multiplied by a factor of 4 and finally the |
393 // smoothed rtt is added which is the initial rtt. | 393 // smoothed rtt is added which is the initial rtt. |
394 QuicTime::Delta expected_delay = | 394 QuicTime::Delta expected_delay = |
395 QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4); | 395 QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4); |
396 EXPECT_EQ(expected_delay, sender_->RetransmissionDelay()); | 396 EXPECT_EQ(expected_delay, sender_->RetransmissionDelay()); |
397 | 397 |
398 for (int i = 0; i < 100; ++i) { | 398 for (int i = 0; i < 100; ++i) { |
399 // Run to make sure that we converge. | 399 // Run to make sure that we converge. |
400 sender_->rtt_stats_.UpdateRtt( | 400 sender_->rtt_stats_.UpdateRtt( |
401 QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs), | 401 QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs), |
402 QuicTime::Delta::Zero(), clock_.Now()); | 402 QuicTime::Delta::Zero(), clock_.Now()); |
403 sender_->rtt_stats_.UpdateRtt( | 403 sender_->rtt_stats_.UpdateRtt( |
404 QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs), | 404 QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs), |
405 QuicTime::Delta::Zero(), clock_.Now()); | 405 QuicTime::Delta::Zero(), clock_.Now()); |
406 } | 406 } |
407 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); | 407 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); |
408 | 408 |
409 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1); | 409 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1); |
410 EXPECT_NEAR(expected_delay.ToMilliseconds(), | 410 EXPECT_NEAR(expected_delay.ToMilliseconds(), |
411 sender_->RetransmissionDelay().ToMilliseconds(), 1); | 411 sender_->RetransmissionDelay().ToMilliseconds(), 1); |
412 EXPECT_EQ( | 412 EXPECT_EQ(static_cast<int64_t>( |
413 static_cast<int64>(sender_->GetCongestionWindow() * kNumMicrosPerSecond / | 413 sender_->GetCongestionWindow() * kNumMicrosPerSecond / |
414 sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()), | 414 sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()), |
415 sender_->BandwidthEstimate().ToBytesPerSecond()); | 415 sender_->BandwidthEstimate().ToBytesPerSecond()); |
416 } | 416 } |
417 | 417 |
418 TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) { | 418 TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) { |
419 const QuicPacketCount kMaxCongestionWindowTCP = 50; | 419 const QuicPacketCount kMaxCongestionWindowTCP = 50; |
420 const int kNumberOfAcks = 100; | 420 const int kNumberOfAcks = 100; |
421 sender_.reset( | 421 sender_.reset( |
422 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); | 422 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); |
423 | 423 |
424 for (int i = 0; i < kNumberOfAcks; ++i) { | 424 for (int i = 0; i < kNumberOfAcks; ++i) { |
425 // Send our full send window. | 425 // Send our full send window. |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 for (int i = 0; i < 10; ++i) { | 706 for (int i = 0; i < 10; ++i) { |
707 // Send our full send window. | 707 // Send our full send window. |
708 SendAvailableSendWindow(); | 708 SendAvailableSendWindow(); |
709 EXPECT_TRUE(sender_->InRecovery()); | 709 EXPECT_TRUE(sender_->InRecovery()); |
710 AckNPackets(2); | 710 AckNPackets(2); |
711 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 711 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
712 } | 712 } |
713 EXPECT_FALSE(sender_->InRecovery()); | 713 EXPECT_FALSE(sender_->InRecovery()); |
714 | 714 |
715 // Out of recovery now. Congestion window should not grow during RTT. | 715 // Out of recovery now. Congestion window should not grow during RTT. |
716 for (uint64 i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) { | 716 for (uint64_t i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) { |
717 // Send our full send window. | 717 // Send our full send window. |
718 SendAvailableSendWindow(); | 718 SendAvailableSendWindow(); |
719 AckNPackets(2); | 719 AckNPackets(2); |
720 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 720 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
721 } | 721 } |
722 | 722 |
723 // Next ack should cause congestion window to grow by 1MSS. | 723 // Next ack should cause congestion window to grow by 1MSS. |
724 SendAvailableSendWindow(); | 724 SendAvailableSendWindow(); |
725 AckNPackets(2); | 725 AckNPackets(2); |
726 expected_send_window += kDefaultTCPMSS; | 726 expected_send_window += kDefaultTCPMSS; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 | 821 |
822 // Resets cwnd and slow start threshold on connection migrations. | 822 // Resets cwnd and slow start threshold on connection migrations. |
823 sender_->OnConnectionMigration(); | 823 sender_->OnConnectionMigration(); |
824 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 824 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
825 EXPECT_EQ(kMaxCongestionWindow, sender_->slowstart_threshold()); | 825 EXPECT_EQ(kMaxCongestionWindow, sender_->slowstart_threshold()); |
826 EXPECT_FALSE(sender_->hybrid_slow_start().started()); | 826 EXPECT_FALSE(sender_->hybrid_slow_start().started()); |
827 } | 827 } |
828 | 828 |
829 } // namespace test | 829 } // namespace test |
830 } // namespace net | 830 } // namespace net |
OLD | NEW |