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 3// found in the LICENSE file. 4 5#include "base/logging.h" 6#include "base/memory/scoped_ptr.h" 7#include "net/quic/congestion_control/hybrid_slow_start.h" 8#include "net/quic/test_tools/mock_clock.h" 9#include "testing/gtest/include/gtest/gtest.h" 10 11namespace net { 12namespace test { 13 14class HybridSlowStartTest : public ::testing::Test { 15 protected: 16 HybridSlowStartTest() 17 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), 18 rtt_(QuicTime::Delta::FromMilliseconds(60)) { 19 } 20 virtual void SetUp() { 21 slow_start_.reset(new HybridSlowStart(&clock_)); 22 } 23 const QuicTime::Delta one_ms_; 24 const QuicTime::Delta rtt_; 25 MockClock clock_; 26 scoped_ptr<HybridSlowStart> slow_start_; 27}; 28 29TEST_F(HybridSlowStartTest, Simple) { 30 QuicPacketSequenceNumber sequence_number = 1; 31 QuicPacketSequenceNumber end_sequence_number = 3; 32 slow_start_->StartReceiveRound(end_sequence_number); 33 34 EXPECT_FALSE(slow_start_->IsEndOfRound(sequence_number++)); 35 36 // Test duplicates. 37 EXPECT_FALSE(slow_start_->IsEndOfRound(sequence_number)); 38 39 EXPECT_FALSE(slow_start_->IsEndOfRound(sequence_number++)); 40 EXPECT_TRUE(slow_start_->IsEndOfRound(sequence_number++)); 41 42 // Test without a new registered end_sequence_number; 43 EXPECT_TRUE(slow_start_->IsEndOfRound(sequence_number++)); 44 45 end_sequence_number = 20; 46 slow_start_->StartReceiveRound(end_sequence_number); 47 while (sequence_number < end_sequence_number) { 48 EXPECT_FALSE(slow_start_->IsEndOfRound(sequence_number++)); 49 } 50 EXPECT_TRUE(slow_start_->IsEndOfRound(sequence_number++)); 51} 52 53// TODO(ianswett): Add tests which more realistically invoke the methods, 54// simulating how actual acks arrive and packets are sent. 55TEST_F(HybridSlowStartTest, AckTrain) { 56 // At a typical RTT 60 ms, assuming that the inter arrival timestamp is 1 ms, 57 // we expect to be able to send a burst of 30 packet before we trigger the 58 // ack train detection. 59 const int kMaxLoopCount = 5; 60 QuicPacketSequenceNumber sequence_number = 2; 61 QuicPacketSequenceNumber end_sequence_number = 2; 62 for (int burst = 0; burst < kMaxLoopCount; ++burst) { 63 slow_start_->StartReceiveRound(end_sequence_number); 64 do { 65 clock_.AdvanceTime(one_ms_); 66 EXPECT_FALSE(slow_start_->ShouldExitSlowStart(rtt_, rtt_, 100)); 67 } while (!slow_start_->IsEndOfRound(sequence_number++)); 68 end_sequence_number *= 2; // Exponential growth. 69 } 70 slow_start_->StartReceiveRound(end_sequence_number); 71 72 for (int n = 0; 73 n < 29 && !slow_start_->IsEndOfRound(sequence_number++); ++n) { 74 clock_.AdvanceTime(one_ms_); 75 EXPECT_FALSE(slow_start_->ShouldExitSlowStart(rtt_, rtt_, 100)); 76 } 77 clock_.AdvanceTime(one_ms_); 78 EXPECT_TRUE(slow_start_->ShouldExitSlowStart(rtt_, rtt_, 100)); 79} 80 81TEST_F(HybridSlowStartTest, Delay) { 82 // We expect to detect the increase at +1/16 of the RTT; hence at a typical 83 // RTT of 60ms the detection will happen at 63.75 ms. 84 const int kHybridStartMinSamples = 8; // Number of acks required to trigger. 85 86 QuicPacketSequenceNumber end_sequence_number = 1; 87 slow_start_->StartReceiveRound(end_sequence_number++); 88 89 // Will not trigger since our lowest RTT in our burst is the same as the long 90 // term RTT provided. 91 for (int n = 0; n < kHybridStartMinSamples; ++n) { 92 EXPECT_FALSE(slow_start_->ShouldExitSlowStart( 93 rtt_.Add(QuicTime::Delta::FromMilliseconds(n)), rtt_, 100)); 94 } 95 slow_start_->StartReceiveRound(end_sequence_number++); 96 for (int n = 1; n < kHybridStartMinSamples; ++n) { 97 EXPECT_FALSE(slow_start_->ShouldExitSlowStart( 98 rtt_.Add(QuicTime::Delta::FromMilliseconds(n + 5)), rtt_, 100)); 99 } 100 // Expect to trigger since all packets in this burst was above the long term 101 // RTT provided. 102 EXPECT_TRUE(slow_start_->ShouldExitSlowStart( 103 rtt_.Add(QuicTime::Delta::FromMilliseconds(5)), rtt_, 100)); 104} 105 106} // namespace test 107} // namespace net 108