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/utility_function.h"
12 
13 #include <stddef.h>
14 
15 #include <cmath>
16 #include <type_traits>
17 #include <vector>
18 
19 #include "api/transport/network_types.h"
20 #include "api/units/data_rate.h"
21 #include "api/units/data_size.h"
22 #include "api/units/time_delta.h"
23 #include "api/units/timestamp.h"
24 #include "test/gtest.h"
25 
26 namespace webrtc {
27 namespace pcc {
28 namespace test {
29 namespace {
30 constexpr double kLossCoefficient = 11.35;
31 constexpr double kThroughputPower = 0.9;
32 constexpr double kThroughputCoefficient = 1;
33 constexpr double kDelayGradientNegativeBound = 10;
34 
35 const Timestamp kStartTime = Timestamp::Micros(0);
36 const TimeDelta kPacketsDelta = TimeDelta::Millis(1);
37 const TimeDelta kIntervalDuration = TimeDelta::Millis(100);
38 const DataRate kSendingBitrate = DataRate::BitsPerSec(1000);
39 
40 const DataSize kDefaultDataSize = DataSize::Bytes(100);
41 const TimeDelta kDefaultDelay = TimeDelta::Millis(100);
42 
CreatePacketResults(const std::vector<Timestamp> & packets_send_times,const std::vector<Timestamp> & packets_received_times={},const std::vector<DataSize> & packets_sizes={})43 std::vector<PacketResult> CreatePacketResults(
44     const std::vector<Timestamp>& packets_send_times,
45     const std::vector<Timestamp>& packets_received_times = {},
46     const std::vector<DataSize>& packets_sizes = {}) {
47   std::vector<PacketResult> packet_results;
48   PacketResult packet_result;
49   SentPacket sent_packet;
50   for (size_t i = 0; i < packets_send_times.size(); ++i) {
51     sent_packet.send_time = packets_send_times[i];
52     if (packets_sizes.empty()) {
53       sent_packet.size = kDefaultDataSize;
54     } else {
55       sent_packet.size = packets_sizes[i];
56     }
57     packet_result.sent_packet = sent_packet;
58     if (packets_received_times.empty()) {
59       packet_result.receive_time = packets_send_times[i] + kDefaultDelay;
60     } else {
61       packet_result.receive_time = packets_received_times[i];
62     }
63     packet_results.push_back(packet_result);
64   }
65   return packet_results;
66 }
67 
68 }  // namespace
69 
TEST(PccVivaceUtilityFunctionTest,UtilityIsThroughputTermIfAllRestCoefficientsAreZero)70 TEST(PccVivaceUtilityFunctionTest,
71      UtilityIsThroughputTermIfAllRestCoefficientsAreZero) {
72   VivaceUtilityFunction utility_function(0, 0, kThroughputCoefficient,
73                                          kThroughputPower, 0,
74                                          kDelayGradientNegativeBound);
75   PccMonitorInterval monitor_interval(kSendingBitrate, kStartTime,
76                                       kIntervalDuration);
77   monitor_interval.OnPacketsFeedback(CreatePacketResults(
78       {kStartTime + kPacketsDelta, kStartTime + 2 * kPacketsDelta,
79        kStartTime + 3 * kPacketsDelta, kStartTime + 2 * kIntervalDuration},
80       {kStartTime + kPacketsDelta + kDefaultDelay, Timestamp::PlusInfinity(),
81        kStartTime + kDefaultDelay + 3 * kPacketsDelta,
82        Timestamp::PlusInfinity()},
83       {kDefaultDataSize, kDefaultDataSize, kDefaultDataSize,
84        kDefaultDataSize}));
85   EXPECT_DOUBLE_EQ(utility_function.Compute(monitor_interval),
86                    kThroughputCoefficient *
87                        std::pow(kSendingBitrate.bps(), kThroughputPower));
88 }
89 
TEST(PccVivaceUtilityFunctionTest,LossTermIsNonZeroIfLossCoefficientIsNonZero)90 TEST(PccVivaceUtilityFunctionTest,
91      LossTermIsNonZeroIfLossCoefficientIsNonZero) {
92   VivaceUtilityFunction utility_function(
93       0, kLossCoefficient, kThroughputCoefficient, kThroughputPower, 0,
94       kDelayGradientNegativeBound);
95   PccMonitorInterval monitor_interval(kSendingBitrate, kStartTime,
96                                       kIntervalDuration);
97   monitor_interval.OnPacketsFeedback(CreatePacketResults(
98       {kStartTime + kPacketsDelta, kStartTime + 2 * kPacketsDelta,
99        kStartTime + 5 * kPacketsDelta, kStartTime + 2 * kIntervalDuration},
100       {kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
101        kStartTime + kDefaultDelay, kStartTime + 3 * kIntervalDuration},
102       {}));
103   // The second packet was lost.
104   EXPECT_DOUBLE_EQ(utility_function.Compute(monitor_interval),
105                    kThroughputCoefficient *
106                            std::pow(kSendingBitrate.bps(), kThroughputPower) -
107                        kLossCoefficient * kSendingBitrate.bps() *
108                            monitor_interval.GetLossRate());
109 }
110 
111 }  // namespace test
112 }  // namespace pcc
113 }  // namespace webrtc
114