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" |
(...skipping 12 matching lines...) Expand all Loading... |
23 // TODO(ianswett): A number of theses tests were written with the assumption of | 23 // TODO(ianswett): A number of theses tests were written with the assumption of |
24 // an initial CWND of 10. They have carefully calculated values which should be | 24 // an initial CWND of 10. They have carefully calculated values which should be |
25 // updated to be based on kInitialCongestionWindowInsecure. | 25 // updated to be based on kInitialCongestionWindowInsecure. |
26 const uint32 kInitialCongestionWindowPackets = 10; | 26 const uint32 kInitialCongestionWindowPackets = 10; |
27 const uint32 kDefaultWindowTCP = | 27 const uint32 kDefaultWindowTCP = |
28 kInitialCongestionWindowPackets * kDefaultTCPMSS; | 28 kInitialCongestionWindowPackets * kDefaultTCPMSS; |
29 const float kRenoBeta = 0.7f; // Reno backoff factor. | 29 const float kRenoBeta = 0.7f; // Reno backoff factor. |
30 | 30 |
31 class TcpCubicSenderPeer : public TcpCubicSender { | 31 class TcpCubicSenderPeer : public TcpCubicSender { |
32 public: | 32 public: |
33 TcpCubicSenderPeer(const QuicClock* clock, | 33 TcpCubicSenderPeer(const QuicClock* clock, bool reno) |
34 bool reno, | 34 : TcpCubicSender(clock, |
35 QuicPacketCount max_tcp_congestion_window) | 35 &rtt_stats_, |
36 : TcpCubicSender( | 36 reno, |
37 clock, &rtt_stats_, reno, kInitialCongestionWindowPackets, | 37 kInitialCongestionWindowPackets, |
38 max_tcp_congestion_window, &stats_) { | 38 &stats_) {} |
39 } | |
40 | 39 |
41 QuicPacketCount congestion_window() { | 40 QuicPacketCount congestion_window() { |
42 return congestion_window_; | 41 return congestion_window_; |
43 } | 42 } |
44 | 43 |
45 QuicPacketCount slowstart_threshold() { | 44 QuicPacketCount slowstart_threshold() { |
46 return slowstart_threshold_; | 45 return slowstart_threshold_; |
47 } | 46 } |
48 | 47 |
49 const HybridSlowStart& hybrid_slow_start() const { | 48 const HybridSlowStart& hybrid_slow_start() const { |
50 return hybrid_slow_start_; | 49 return hybrid_slow_start_; |
51 } | 50 } |
52 | 51 |
53 float GetRenoBeta() const { | 52 float GetRenoBeta() const { |
54 return RenoBeta(); | 53 return RenoBeta(); |
55 } | 54 } |
56 | 55 |
57 RttStats rtt_stats_; | 56 RttStats rtt_stats_; |
58 QuicConnectionStats stats_; | 57 QuicConnectionStats stats_; |
59 }; | 58 }; |
60 | 59 |
61 class TcpCubicSenderTest : public ::testing::Test { | 60 class TcpCubicSenderTest : public ::testing::Test { |
62 protected: | 61 protected: |
63 TcpCubicSenderTest() | 62 TcpCubicSenderTest() |
64 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), | 63 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), |
65 sender_(new TcpCubicSenderPeer(&clock_, true, | 64 sender_(new TcpCubicSenderPeer(&clock_, true)), |
66 kMaxTcpCongestionWindow)), | |
67 sequence_number_(1), | 65 sequence_number_(1), |
68 acked_sequence_number_(0), | 66 acked_sequence_number_(0), |
69 bytes_in_flight_(0) { | 67 bytes_in_flight_(0) { |
70 standard_packet_.bytes_sent = kDefaultTCPMSS; | 68 standard_packet_.bytes_sent = kDefaultTCPMSS; |
71 } | 69 } |
72 | 70 |
73 int SendAvailableSendWindow() { | 71 int SendAvailableSendWindow() { |
74 // Send as long as TimeUntilSend returns Zero. | 72 // Send as long as TimeUntilSend returns Zero. |
75 int packets_sent = 0; | 73 int packets_sent = 0; |
76 bool can_send = sender_->TimeUntilSend( | 74 bool can_send = sender_->TimeUntilSend( |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 const QuicByteCount cwnd = sender_->GetCongestionWindow(); | 199 const QuicByteCount cwnd = sender_->GetCongestionWindow(); |
202 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd); | 200 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd); |
203 EXPECT_FALSE(sender_->HasReliableBandwidthEstimate()); | 201 EXPECT_FALSE(sender_->HasReliableBandwidthEstimate()); |
204 EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta( | 202 EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta( |
205 cwnd, sender_->rtt_stats_.smoothed_rtt()), | 203 cwnd, sender_->rtt_stats_.smoothed_rtt()), |
206 sender_->BandwidthEstimate()); | 204 sender_->BandwidthEstimate()); |
207 } | 205 } |
208 | 206 |
209 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { | 207 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { |
210 sender_->SetNumEmulatedConnections(1); | 208 sender_->SetNumEmulatedConnections(1); |
211 EXPECT_EQ(kMaxTcpCongestionWindow * kDefaultTCPMSS, | |
212 sender_->GetSlowStartThreshold()); | |
213 | 209 |
214 // Make sure that we fall out of slow start when we send ACK train longer | 210 // Make sure that we fall out of slow start when we send ACK train longer |
215 // than half the RTT, in this test case 30ms, which is more than 30 calls to | 211 // than half the RTT, in this test case 30ms, which is more than 30 calls to |
216 // Ack2Packets in one round. | 212 // Ack2Packets in one round. |
217 // Since we start at 10 packet first round will be 5 second round 10 etc | 213 // Since we start at 10 packet first round will be 5 second round 10 etc |
218 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 | 214 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 |
219 const int kNumberOfAcks = 65; | 215 const int kNumberOfAcks = 65; |
220 for (int i = 0; i < kNumberOfAcks; ++i) { | 216 for (int i = 0; i < kNumberOfAcks; ++i) { |
221 // Send our full send window. | 217 // Send our full send window. |
222 SendAvailableSendWindow(); | 218 SendAvailableSendWindow(); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 | 407 |
412 // Exit recovery and return to sending at the new rate. | 408 // Exit recovery and return to sending at the new rate. |
413 for (int i = 0; i < kNumberOfAcks; ++i) { | 409 for (int i = 0; i < kNumberOfAcks; ++i) { |
414 AckNPackets(1); | 410 AckNPackets(1); |
415 EXPECT_EQ(1, SendAvailableSendWindow()); | 411 EXPECT_EQ(1, SendAvailableSendWindow()); |
416 } | 412 } |
417 } | 413 } |
418 | 414 |
419 TEST_F(TcpCubicSenderTest, RTOCongestionWindow) { | 415 TEST_F(TcpCubicSenderTest, RTOCongestionWindow) { |
420 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 416 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
421 EXPECT_EQ(kMaxTcpCongestionWindow, sender_->slowstart_threshold()); | |
422 | |
423 // Expect the window to decrease to the minimum once the RTO fires | 417 // Expect the window to decrease to the minimum once the RTO fires |
424 // and slow start threshold to be set to 1/2 of the CWND. | 418 // and slow start threshold to be set to 1/2 of the CWND. |
425 sender_->OnRetransmissionTimeout(true); | 419 sender_->OnRetransmissionTimeout(true); |
426 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow()); | 420 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow()); |
427 EXPECT_EQ(5u, sender_->slowstart_threshold()); | 421 EXPECT_EQ(5u, sender_->slowstart_threshold()); |
428 } | 422 } |
429 | 423 |
430 TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) { | 424 TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) { |
431 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 425 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
432 | 426 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1); | 459 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1); |
466 EXPECT_NEAR(expected_delay.ToMilliseconds(), | 460 EXPECT_NEAR(expected_delay.ToMilliseconds(), |
467 sender_->RetransmissionDelay().ToMilliseconds(), | 461 sender_->RetransmissionDelay().ToMilliseconds(), |
468 1); | 462 1); |
469 EXPECT_EQ(static_cast<int64>( | 463 EXPECT_EQ(static_cast<int64>( |
470 sender_->GetCongestionWindow() * kNumMicrosPerSecond / | 464 sender_->GetCongestionWindow() * kNumMicrosPerSecond / |
471 sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()), | 465 sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()), |
472 sender_->BandwidthEstimate().ToBytesPerSecond()); | 466 sender_->BandwidthEstimate().ToBytesPerSecond()); |
473 } | 467 } |
474 | 468 |
475 TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) { | |
476 const QuicPacketCount kMaxCongestionWindowTCP = 50; | |
477 const int kNumberOfAcks = 100; | |
478 sender_.reset( | |
479 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); | |
480 | |
481 for (int i = 0; i < kNumberOfAcks; ++i) { | |
482 // Send our full send window. | |
483 SendAvailableSendWindow(); | |
484 AckNPackets(2); | |
485 } | |
486 QuicByteCount expected_send_window = | |
487 kMaxCongestionWindowTCP * kDefaultTCPMSS; | |
488 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
489 } | |
490 | |
491 TEST_F(TcpCubicSenderTest, TcpRenoMaxCongestionWindow) { | |
492 const QuicPacketCount kMaxCongestionWindowTCP = 50; | |
493 const int kNumberOfAcks = 1000; | |
494 sender_.reset( | |
495 new TcpCubicSenderPeer(&clock_, true, kMaxCongestionWindowTCP)); | |
496 | |
497 SendAvailableSendWindow(); | |
498 AckNPackets(2); | |
499 // Make sure we fall out of slow start. | |
500 LoseNPackets(1); | |
501 | |
502 for (int i = 0; i < kNumberOfAcks; ++i) { | |
503 // Send our full send window. | |
504 SendAvailableSendWindow(); | |
505 AckNPackets(2); | |
506 } | |
507 | |
508 QuicByteCount expected_send_window = | |
509 kMaxCongestionWindowTCP * kDefaultTCPMSS; | |
510 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
511 } | |
512 | |
513 TEST_F(TcpCubicSenderTest, TcpCubicMaxCongestionWindow) { | |
514 const QuicPacketCount kMaxCongestionWindowTCP = 50; | |
515 // Set to 10000 to compensate for small cubic alpha. | |
516 const int kNumberOfAcks = 10000; | |
517 | |
518 sender_.reset( | |
519 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); | |
520 | |
521 SendAvailableSendWindow(); | |
522 AckNPackets(2); | |
523 // Make sure we fall out of slow start. | |
524 LoseNPackets(1); | |
525 | |
526 for (int i = 0; i < kNumberOfAcks; ++i) { | |
527 // Send our full send window. | |
528 SendAvailableSendWindow(); | |
529 AckNPackets(2); | |
530 } | |
531 | |
532 QuicByteCount expected_send_window = | |
533 kMaxCongestionWindowTCP * kDefaultTCPMSS; | |
534 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
535 } | |
536 | |
537 TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) { | 469 TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) { |
538 SendAvailableSendWindow(); | 470 SendAvailableSendWindow(); |
539 const QuicByteCount initial_window = sender_->GetCongestionWindow(); | 471 const QuicByteCount initial_window = sender_->GetCongestionWindow(); |
540 LosePacket(acked_sequence_number_ + 1); | 472 LosePacket(acked_sequence_number_ + 1); |
541 const QuicByteCount post_loss_window = sender_->GetCongestionWindow(); | 473 const QuicByteCount post_loss_window = sender_->GetCongestionWindow(); |
542 EXPECT_GT(initial_window, post_loss_window); | 474 EXPECT_GT(initial_window, post_loss_window); |
543 LosePacket(acked_sequence_number_ + 3); | 475 LosePacket(acked_sequence_number_ + 3); |
544 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow()); | 476 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow()); |
545 LosePacket(sequence_number_ - 1); | 477 LosePacket(sequence_number_ - 1); |
546 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow()); | 478 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow()); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 EXPECT_EQ(10u, sender_->congestion_window()); | 640 EXPECT_EQ(10u, sender_->congestion_window()); |
709 | 641 |
710 // If the estimate is new enough, make sure it is used. | 642 // If the estimate is new enough, make sure it is used. |
711 cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() - | 643 cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() - |
712 (kNumSecondsPerHour - 1)); | 644 (kNumSecondsPerHour - 1)); |
713 EXPECT_TRUE(sender_->ResumeConnectionState(cached_network_params)); | 645 EXPECT_TRUE(sender_->ResumeConnectionState(cached_network_params)); |
714 EXPECT_EQ(kNumberOfPackets, sender_->congestion_window()); | 646 EXPECT_EQ(kNumberOfPackets, sender_->congestion_window()); |
715 | 647 |
716 // Resumed CWND is limited to be in a sensible range. | 648 // Resumed CWND is limited to be in a sensible range. |
717 cached_network_params.set_bandwidth_estimate_bytes_per_second( | 649 cached_network_params.set_bandwidth_estimate_bytes_per_second( |
718 (kMaxTcpCongestionWindow + 1) * kMaxPacketSize); | 650 (kMaxCongestionWindowForBandwidthResumption + 1) * kMaxPacketSize); |
719 EXPECT_TRUE(sender_->ResumeConnectionState(cached_network_params)); | 651 EXPECT_TRUE(sender_->ResumeConnectionState(cached_network_params)); |
720 EXPECT_EQ(kMaxTcpCongestionWindow, sender_->congestion_window()); | 652 EXPECT_EQ(kMaxCongestionWindowForBandwidthResumption, |
| 653 sender_->congestion_window()); |
721 | 654 |
722 cached_network_params.set_bandwidth_estimate_bytes_per_second( | 655 cached_network_params.set_bandwidth_estimate_bytes_per_second( |
723 (kMinCongestionWindowForBandwidthResumption - 1) * kMaxPacketSize); | 656 (kMinCongestionWindowForBandwidthResumption - 1) * kMaxPacketSize); |
724 EXPECT_TRUE(sender_->ResumeConnectionState(cached_network_params)); | 657 EXPECT_TRUE(sender_->ResumeConnectionState(cached_network_params)); |
725 EXPECT_EQ(kMinCongestionWindowForBandwidthResumption, | 658 EXPECT_EQ(kMinCongestionWindowForBandwidthResumption, |
726 sender_->congestion_window()); | 659 sender_->congestion_window()); |
727 } | 660 } |
728 | 661 |
729 } // namespace test | 662 } // namespace test |
730 } // namespace net | 663 } // namespace net |
OLD | NEW |