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