1 // Copyright 2014 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 "net/quic/congestion_control/rtt_stats.h" 6 7 #include "base/logging.h" 8 #include "testing/gtest/include/gtest/gtest.h" 9 10 namespace net { 11 namespace test { 12 13 class RttStatsPeer { 14 public: 15 static QuicTime::Delta GetHalfWindowRtt(const RttStats* rtt_stats) { 16 return rtt_stats->half_window_rtt_.rtt; 17 } 18 19 static QuicTime::Delta GetQuarterWindowRtt(const RttStats* rtt_stats) { 20 return rtt_stats->quarter_window_rtt_.rtt; 21 } 22 }; 23 24 class RttStatsTest : public ::testing::Test { 25 protected: 26 RttStats rtt_stats_; 27 }; 28 29 TEST_F(RttStatsTest, MinRtt) { 30 rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100), 31 QuicTime::Delta::Zero(), 32 QuicTime::Zero()); 33 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats_.min_rtt()); 34 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), 35 rtt_stats_.recent_min_rtt()); 36 rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10), 37 QuicTime::Delta::Zero(), 38 QuicTime::Zero().Add( 39 QuicTime::Delta::FromMilliseconds(10))); 40 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); 41 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.recent_min_rtt()); 42 rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50), 43 QuicTime::Delta::Zero(), 44 QuicTime::Zero().Add( 45 QuicTime::Delta::FromMilliseconds(20))); 46 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); 47 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.recent_min_rtt()); 48 rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50), 49 QuicTime::Delta::Zero(), 50 QuicTime::Zero().Add( 51 QuicTime::Delta::FromMilliseconds(30))); 52 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); 53 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.recent_min_rtt()); 54 rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50), 55 QuicTime::Delta::Zero(), 56 QuicTime::Zero().Add( 57 QuicTime::Delta::FromMilliseconds(40))); 58 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); 59 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.recent_min_rtt()); 60 } 61 62 TEST_F(RttStatsTest, RecentMinRtt) { 63 rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10), 64 QuicTime::Delta::Zero(), 65 QuicTime::Zero()); 66 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); 67 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.recent_min_rtt()); 68 69 rtt_stats_.SampleNewRecentMinRtt(4); 70 for (int i = 0; i < 3; ++i) { 71 rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50), 72 QuicTime::Delta::Zero(), 73 QuicTime::Zero()); 74 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); 75 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), 76 rtt_stats_.recent_min_rtt()); 77 } 78 rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50), 79 QuicTime::Delta::Zero(), 80 QuicTime::Zero()); 81 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); 82 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50), rtt_stats_.recent_min_rtt()); 83 } 84 85 TEST_F(RttStatsTest, WindowedRecentMinRtt) { 86 // Set the window to 99ms, so 25ms is more than a quarter rtt. 87 rtt_stats_.set_recent_min_rtt_window(QuicTime::Delta::FromMilliseconds(99)); 88 89 QuicTime now = QuicTime::Zero(); 90 QuicTime::Delta rtt_sample = QuicTime::Delta::FromMilliseconds(10); 91 rtt_stats_.UpdateRtt(rtt_sample, QuicTime::Delta::Zero(), now); 92 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); 93 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.recent_min_rtt()); 94 95 // Gradually increase the rtt samples and ensure the recent_min_rtt starts 96 // rising. 97 for (int i = 0; i < 8; ++i) { 98 now = now.Add(QuicTime::Delta::FromMilliseconds(25)); 99 rtt_sample = rtt_sample.Add(QuicTime::Delta::FromMilliseconds(10)); 100 rtt_stats_.UpdateRtt(rtt_sample, QuicTime::Delta::Zero(), now); 101 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); 102 EXPECT_EQ(rtt_sample, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_)); 103 EXPECT_EQ(rtt_sample.Subtract(QuicTime::Delta::FromMilliseconds(10)), 104 RttStatsPeer::GetHalfWindowRtt(&rtt_stats_)); 105 if (i < 3) { 106 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), 107 rtt_stats_.recent_min_rtt()); 108 } else if (i < 5) { 109 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(30), 110 rtt_stats_.recent_min_rtt()); 111 } else if (i < 7) { 112 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50), 113 rtt_stats_.recent_min_rtt()); 114 } else { 115 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70), 116 rtt_stats_.recent_min_rtt()); 117 } 118 } 119 120 // A new quarter rtt low sets that, but nothing else. 121 rtt_sample = rtt_sample.Subtract(QuicTime::Delta::FromMilliseconds(5)); 122 rtt_stats_.UpdateRtt(rtt_sample, QuicTime::Delta::Zero(), now); 123 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); 124 EXPECT_EQ(rtt_sample, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_)); 125 EXPECT_EQ(rtt_sample.Subtract(QuicTime::Delta::FromMilliseconds(5)), 126 RttStatsPeer::GetHalfWindowRtt(&rtt_stats_)); 127 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70), 128 rtt_stats_.recent_min_rtt()); 129 130 // A new half rtt low sets that and the quarter rtt low. 131 rtt_sample = rtt_sample.Subtract(QuicTime::Delta::FromMilliseconds(15)); 132 rtt_stats_.UpdateRtt(rtt_sample, QuicTime::Delta::Zero(), now); 133 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); 134 EXPECT_EQ(rtt_sample, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_)); 135 EXPECT_EQ(rtt_sample, RttStatsPeer::GetHalfWindowRtt(&rtt_stats_)); 136 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(70), 137 rtt_stats_.recent_min_rtt()); 138 139 // A new full window loss sets the recent_min_rtt, but not min_rtt. 140 rtt_sample = QuicTime::Delta::FromMilliseconds(65); 141 rtt_stats_.UpdateRtt(rtt_sample, QuicTime::Delta::Zero(), now); 142 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt()); 143 EXPECT_EQ(rtt_sample, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_)); 144 EXPECT_EQ(rtt_sample, RttStatsPeer::GetHalfWindowRtt(&rtt_stats_)); 145 EXPECT_EQ(rtt_sample, rtt_stats_.recent_min_rtt()); 146 147 // A new all time low sets both the min_rtt and the recent_min_rtt. 148 rtt_sample = QuicTime::Delta::FromMilliseconds(5); 149 rtt_stats_.UpdateRtt(rtt_sample, QuicTime::Delta::Zero(), now); 150 151 EXPECT_EQ(rtt_sample, rtt_stats_.min_rtt()); 152 EXPECT_EQ(rtt_sample, RttStatsPeer::GetQuarterWindowRtt(&rtt_stats_)); 153 EXPECT_EQ(rtt_sample, RttStatsPeer::GetHalfWindowRtt(&rtt_stats_)); 154 EXPECT_EQ(rtt_sample, rtt_stats_.recent_min_rtt()); 155 } 156 157 TEST_F(RttStatsTest, ExpireSmoothedMetrics) { 158 QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(10); 159 rtt_stats_.UpdateRtt(initial_rtt, QuicTime::Delta::Zero(), QuicTime::Zero()); 160 EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt()); 161 EXPECT_EQ(initial_rtt, rtt_stats_.recent_min_rtt()); 162 EXPECT_EQ(initial_rtt, rtt_stats_.SmoothedRtt()); 163 164 EXPECT_EQ(initial_rtt.Multiply(0.5), rtt_stats_.mean_deviation()); 165 166 // Update once with a 20ms RTT. 167 QuicTime::Delta doubled_rtt = initial_rtt.Multiply(2); 168 rtt_stats_.UpdateRtt(doubled_rtt, QuicTime::Delta::Zero(), QuicTime::Zero()); 169 EXPECT_EQ(initial_rtt.Multiply(1.125), rtt_stats_.SmoothedRtt()); 170 171 // Expire the smoothed metrics, increasing smoothed rtt and mean deviation. 172 rtt_stats_.ExpireSmoothedMetrics(); 173 EXPECT_EQ(doubled_rtt, rtt_stats_.SmoothedRtt()); 174 EXPECT_EQ(initial_rtt.Multiply(0.875), rtt_stats_.mean_deviation()); 175 176 // Now go back down to 5ms and expire the smoothed metrics, and ensure the 177 // mean deviation increases to 15ms. 178 QuicTime::Delta half_rtt = initial_rtt.Multiply(0.5); 179 rtt_stats_.UpdateRtt(half_rtt, QuicTime::Delta::Zero(), QuicTime::Zero()); 180 EXPECT_GT(doubled_rtt, rtt_stats_.SmoothedRtt()); 181 EXPECT_LT(initial_rtt, rtt_stats_.mean_deviation()); 182 } 183 184 } // namespace test 185 } // namespace net 186