1 /*
2  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/congestion_controller/goog_cc/trendline_estimator.h"
12 
13 #include <algorithm>
14 #include <numeric>
15 #include <vector>
16 
17 #include "api/transport/field_trial_based_config.h"
18 #include "rtc_base/random.h"
19 #include "test/gtest.h"
20 
21 namespace webrtc {
22 namespace {
23 
24 class PacketTimeGenerator {
25  public:
PacketTimeGenerator(int64_t initial_clock,double time_between_packets)26   PacketTimeGenerator(int64_t initial_clock, double time_between_packets)
27       : initial_clock_(initial_clock),
28         time_between_packets_(time_between_packets),
29         packets_(0) {}
operator ()()30   int64_t operator()() {
31     return initial_clock_ + time_between_packets_ * packets_++;
32   }
33 
34  private:
35   const int64_t initial_clock_;
36   const double time_between_packets_;
37   size_t packets_;
38 };
39 
40 class TrendlineEstimatorTest : public testing::Test {
41  public:
TrendlineEstimatorTest()42   TrendlineEstimatorTest()
43       : send_times(kPacketCount),
44         recv_times(kPacketCount),
45         packet_sizes(kPacketCount),
46         config(),
47         estimator(&config, nullptr),
48         count(1) {
49     std::fill(packet_sizes.begin(), packet_sizes.end(), kPacketSizeBytes);
50   }
51 
RunTestUntilStateChange()52   void RunTestUntilStateChange() {
53     RTC_DCHECK_EQ(send_times.size(), kPacketCount);
54     RTC_DCHECK_EQ(recv_times.size(), kPacketCount);
55     RTC_DCHECK_EQ(packet_sizes.size(), kPacketCount);
56     RTC_DCHECK_GE(count, 1);
57     RTC_DCHECK_LT(count, kPacketCount);
58 
59     auto initial_state = estimator.State();
60     for (; count < kPacketCount; count++) {
61       double recv_delta = recv_times[count] - recv_times[count - 1];
62       double send_delta = send_times[count] - send_times[count - 1];
63       estimator.Update(recv_delta, send_delta, send_times[count],
64                        recv_times[count], packet_sizes[count], true);
65       if (estimator.State() != initial_state) {
66         return;
67       }
68     }
69   }
70 
71  protected:
72   const size_t kPacketCount = 25;
73   const size_t kPacketSizeBytes = 1200;
74   std::vector<int64_t> send_times;
75   std::vector<int64_t> recv_times;
76   std::vector<size_t> packet_sizes;
77   const FieldTrialBasedConfig config;
78   TrendlineEstimator estimator;
79   size_t count;
80 };
81 }  // namespace
82 
TEST_F(TrendlineEstimatorTest,Normal)83 TEST_F(TrendlineEstimatorTest, Normal) {
84   PacketTimeGenerator send_time_generator(123456789 /*initial clock*/,
85                                           20 /*20 ms between sent packets*/);
86   std::generate(send_times.begin(), send_times.end(), send_time_generator);
87 
88   PacketTimeGenerator recv_time_generator(987654321 /*initial clock*/,
89                                           20 /*delivered at the same pace*/);
90   std::generate(recv_times.begin(), recv_times.end(), recv_time_generator);
91 
92   EXPECT_EQ(estimator.State(), BandwidthUsage::kBwNormal);
93   RunTestUntilStateChange();
94   EXPECT_EQ(estimator.State(), BandwidthUsage::kBwNormal);
95   EXPECT_EQ(count, kPacketCount);  // All packets processed
96 }
97 
TEST_F(TrendlineEstimatorTest,Overusing)98 TEST_F(TrendlineEstimatorTest, Overusing) {
99   PacketTimeGenerator send_time_generator(123456789 /*initial clock*/,
100                                           20 /*20 ms between sent packets*/);
101   std::generate(send_times.begin(), send_times.end(), send_time_generator);
102 
103   PacketTimeGenerator recv_time_generator(987654321 /*initial clock*/,
104                                           1.1 * 20 /*10% slower delivery*/);
105   std::generate(recv_times.begin(), recv_times.end(), recv_time_generator);
106 
107   EXPECT_EQ(estimator.State(), BandwidthUsage::kBwNormal);
108   RunTestUntilStateChange();
109   EXPECT_EQ(estimator.State(), BandwidthUsage::kBwOverusing);
110   RunTestUntilStateChange();
111   EXPECT_EQ(estimator.State(), BandwidthUsage::kBwOverusing);
112   EXPECT_EQ(count, kPacketCount);  // All packets processed
113 }
114 
TEST_F(TrendlineEstimatorTest,Underusing)115 TEST_F(TrendlineEstimatorTest, Underusing) {
116   PacketTimeGenerator send_time_generator(123456789 /*initial clock*/,
117                                           20 /*20 ms between sent packets*/);
118   std::generate(send_times.begin(), send_times.end(), send_time_generator);
119 
120   PacketTimeGenerator recv_time_generator(987654321 /*initial clock*/,
121                                           0.85 * 20 /*15% faster delivery*/);
122   std::generate(recv_times.begin(), recv_times.end(), recv_time_generator);
123 
124   EXPECT_EQ(estimator.State(), BandwidthUsage::kBwNormal);
125   RunTestUntilStateChange();
126   EXPECT_EQ(estimator.State(), BandwidthUsage::kBwUnderusing);
127   RunTestUntilStateChange();
128   EXPECT_EQ(estimator.State(), BandwidthUsage::kBwUnderusing);
129   EXPECT_EQ(count, kPacketCount);  // All packets processed
130 }
131 
TEST_F(TrendlineEstimatorTest,IncludesSmallPacketsByDefault)132 TEST_F(TrendlineEstimatorTest, IncludesSmallPacketsByDefault) {
133   PacketTimeGenerator send_time_generator(123456789 /*initial clock*/,
134                                           20 /*20 ms between sent packets*/);
135   std::generate(send_times.begin(), send_times.end(), send_time_generator);
136 
137   PacketTimeGenerator recv_time_generator(987654321 /*initial clock*/,
138                                           1.1 * 20 /*10% slower delivery*/);
139   std::generate(recv_times.begin(), recv_times.end(), recv_time_generator);
140 
141   std::fill(packet_sizes.begin(), packet_sizes.end(), 100);
142 
143   EXPECT_EQ(estimator.State(), BandwidthUsage::kBwNormal);
144   RunTestUntilStateChange();
145   EXPECT_EQ(estimator.State(), BandwidthUsage::kBwOverusing);
146   RunTestUntilStateChange();
147   EXPECT_EQ(estimator.State(), BandwidthUsage::kBwOverusing);
148   EXPECT_EQ(count, kPacketCount);  // All packets processed
149 }
150 
151 }  // namespace webrtc
152