Home | History | Annotate | Download | only in congestion_control
      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