1 /*
2  *  Copyright (c) 2018 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/pcc/monitor_interval.h"
12 
13 #include <stddef.h>
14 
15 #include "test/gtest.h"
16 
17 namespace webrtc {
18 namespace pcc {
19 namespace test {
20 namespace {
21 const DataRate kTargetSendingRate = DataRate::KilobitsPerSec(300);
22 const Timestamp kStartTime = Timestamp::Micros(0);
23 const TimeDelta kPacketsDelta = TimeDelta::Millis(1);
24 const TimeDelta kIntervalDuration = TimeDelta::Millis(100);
25 const TimeDelta kDefaultDelay = TimeDelta::Millis(100);
26 const DataSize kDefaultPacketSize = DataSize::Bytes(100);
27 constexpr double kDelayGradientThreshold = 0.01;
28 
CreatePacketResults(const std::vector<Timestamp> & packets_send_times,const std::vector<Timestamp> & packets_received_times={},const std::vector<DataSize> & packets_sizes={})29 std::vector<PacketResult> CreatePacketResults(
30     const std::vector<Timestamp>& packets_send_times,
31     const std::vector<Timestamp>& packets_received_times = {},
32     const std::vector<DataSize>& packets_sizes = {}) {
33   std::vector<PacketResult> packet_results;
34   for (size_t i = 0; i < packets_send_times.size(); ++i) {
35     SentPacket sent_packet;
36     sent_packet.send_time = packets_send_times[i];
37     if (packets_sizes.empty()) {
38       sent_packet.size = kDefaultPacketSize;
39     } else {
40       sent_packet.size = packets_sizes[i];
41     }
42     PacketResult packet_result;
43     packet_result.sent_packet = sent_packet;
44     if (packets_received_times.empty()) {
45       packet_result.receive_time = packets_send_times[i] + kDefaultDelay;
46     } else {
47       packet_result.receive_time = packets_received_times[i];
48     }
49     packet_results.push_back(packet_result);
50   }
51   return packet_results;
52 }
53 
54 }  // namespace
55 
TEST(PccMonitorIntervalTest,InitialValuesAreEqualToOnesSetInConstructor)56 TEST(PccMonitorIntervalTest, InitialValuesAreEqualToOnesSetInConstructor) {
57   PccMonitorInterval interval{kTargetSendingRate, kStartTime,
58                               kIntervalDuration};
59   EXPECT_EQ(interval.IsFeedbackCollectionDone(), false);
60   EXPECT_EQ(interval.GetEndTime(), kStartTime + kIntervalDuration);
61   EXPECT_EQ(interval.GetTargetSendingRate(), kTargetSendingRate);
62 }
63 
TEST(PccMonitorIntervalTest,IndicatesDoneWhenFeedbackReceivedAfterInterval)64 TEST(PccMonitorIntervalTest, IndicatesDoneWhenFeedbackReceivedAfterInterval) {
65   PccMonitorInterval interval{kTargetSendingRate, kStartTime,
66                               kIntervalDuration};
67   interval.OnPacketsFeedback(CreatePacketResults({kStartTime}));
68   EXPECT_EQ(interval.IsFeedbackCollectionDone(), false);
69   interval.OnPacketsFeedback(
70       CreatePacketResults({kStartTime, kStartTime + kIntervalDuration}));
71   EXPECT_EQ(interval.IsFeedbackCollectionDone(), false);
72   interval.OnPacketsFeedback(CreatePacketResults(
73       {kStartTime + kIntervalDuration, kStartTime + 2 * kIntervalDuration}));
74   EXPECT_EQ(interval.IsFeedbackCollectionDone(), true);
75 }
76 
TEST(PccMonitorIntervalTest,LossRateIsOneThirdIfLostOnePacketOutOfThree)77 TEST(PccMonitorIntervalTest, LossRateIsOneThirdIfLostOnePacketOutOfThree) {
78   PccMonitorInterval interval{kTargetSendingRate, kStartTime,
79                               kIntervalDuration};
80   std::vector<Timestamp> start_times = {
81       kStartTime, kStartTime + 0.1 * kIntervalDuration,
82       kStartTime + 0.5 * kIntervalDuration, kStartTime + kIntervalDuration,
83       kStartTime + 2 * kIntervalDuration};
84   std::vector<Timestamp> end_times = {
85       kStartTime + 2 * kIntervalDuration, kStartTime + 2 * kIntervalDuration,
86       Timestamp::PlusInfinity(), kStartTime + 2 * kIntervalDuration,
87       kStartTime + 4 * kIntervalDuration};
88   std::vector<DataSize> packet_sizes = {
89       kDefaultPacketSize, 2 * kDefaultPacketSize, 3 * kDefaultPacketSize,
90       4 * kDefaultPacketSize, 5 * kDefaultPacketSize};
91   std::vector<PacketResult> packet_results =
92       CreatePacketResults(start_times, end_times, packet_sizes);
93   interval.OnPacketsFeedback(packet_results);
94   EXPECT_EQ(interval.IsFeedbackCollectionDone(), true);
95 
96   EXPECT_DOUBLE_EQ(interval.GetLossRate(), 1. / 3);
97 }
98 
TEST(PccMonitorIntervalTest,DelayGradientIsZeroIfNoChangeInPacketDelay)99 TEST(PccMonitorIntervalTest, DelayGradientIsZeroIfNoChangeInPacketDelay) {
100   PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
101                                       kIntervalDuration);
102   monitor_interval.OnPacketsFeedback(CreatePacketResults(
103       {kStartTime + kPacketsDelta, kStartTime + 2 * kPacketsDelta,
104        kStartTime + 3 * kPacketsDelta, kStartTime + 2 * kIntervalDuration},
105       {kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
106        kStartTime + kDefaultDelay + 2 * kPacketsDelta,
107        Timestamp::PlusInfinity()},
108       {}));
109   // Delay gradient should be zero, because both received packets have the
110   // same one way delay.
111   EXPECT_DOUBLE_EQ(
112       monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 0);
113 }
114 
TEST(PccMonitorIntervalTest,DelayGradientIsZeroWhenOnePacketSentInMonitorInterval)115 TEST(PccMonitorIntervalTest,
116      DelayGradientIsZeroWhenOnePacketSentInMonitorInterval) {
117   PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
118                                       kIntervalDuration);
119   monitor_interval.OnPacketsFeedback(CreatePacketResults(
120       {kStartTime + kPacketsDelta, kStartTime + 2 * kIntervalDuration},
121       {kStartTime + kDefaultDelay, kStartTime + 3 * kIntervalDuration}, {}));
122   // Only one received packet belongs to the monitor_interval, delay gradient
123   // should be zero in this case.
124   EXPECT_DOUBLE_EQ(
125       monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 0);
126 }
127 
TEST(PccMonitorIntervalTest,DelayGradientIsOne)128 TEST(PccMonitorIntervalTest, DelayGradientIsOne) {
129   PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
130                                       kIntervalDuration);
131   monitor_interval.OnPacketsFeedback(CreatePacketResults(
132       {kStartTime + kPacketsDelta, kStartTime + 2 * kPacketsDelta,
133        kStartTime + 3 * kPacketsDelta, kStartTime + 3 * kIntervalDuration},
134       {kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
135        kStartTime + 4 * kPacketsDelta + kDefaultDelay,
136        kStartTime + 3 * kIntervalDuration},
137       {}));
138   EXPECT_DOUBLE_EQ(
139       monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 1);
140 }
141 
TEST(PccMonitorIntervalTest,DelayGradientIsMinusOne)142 TEST(PccMonitorIntervalTest, DelayGradientIsMinusOne) {
143   PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
144                                       kIntervalDuration);
145   monitor_interval.OnPacketsFeedback(CreatePacketResults(
146       {kStartTime + kPacketsDelta, kStartTime + 2 * kPacketsDelta,
147        kStartTime + 5 * kPacketsDelta, kStartTime + 2 * kIntervalDuration},
148       {kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
149        kStartTime + kDefaultDelay, kStartTime + 3 * kIntervalDuration},
150       {}));
151   EXPECT_DOUBLE_EQ(
152       monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), -1);
153 }
154 
TEST(PccMonitorIntervalTest,DelayGradientIsZeroIfItSmallerWhenGradientThreshold)155 TEST(PccMonitorIntervalTest,
156      DelayGradientIsZeroIfItSmallerWhenGradientThreshold) {
157   PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
158                                       kIntervalDuration);
159   monitor_interval.OnPacketsFeedback(CreatePacketResults(
160       {kStartTime + kPacketsDelta, kStartTime + kPacketsDelta,
161        kStartTime + 102 * kPacketsDelta, kStartTime + 2 * kIntervalDuration},
162       {kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
163        kStartTime + kDefaultDelay + kPacketsDelta,
164        kStartTime + 3 * kIntervalDuration},
165       {}));
166   // Delay gradient is less than 0.01 hence should be treated as zero.
167   EXPECT_DOUBLE_EQ(
168       monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 0);
169 }
170 
TEST(PccMonitorIntervalTest,DelayGradientIsZeroWhenAllPacketsSentAtTheSameTime)171 TEST(PccMonitorIntervalTest,
172      DelayGradientIsZeroWhenAllPacketsSentAtTheSameTime) {
173   PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
174                                       kIntervalDuration);
175   monitor_interval.OnPacketsFeedback(CreatePacketResults(
176       {kStartTime + kPacketsDelta, kStartTime + kPacketsDelta,
177        kStartTime + kPacketsDelta, kStartTime + 2 * kIntervalDuration},
178       {kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
179        kStartTime + kDefaultDelay + kPacketsDelta,
180        kStartTime + 3 * kIntervalDuration},
181       {}));
182   // If all packets were sent at the same time, then delay gradient should be
183   // zero.
184   EXPECT_DOUBLE_EQ(
185       monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 0);
186 }
187 
188 }  // namespace test
189 }  // namespace pcc
190 }  // namespace webrtc
191