blob: 65bd8611d63e16fd6400854253064da943056e8e [file] [log] [blame]
/*
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/congestion_controller/pcc/monitor_interval.h"
#include <stddef.h>
#include "test/gtest.h"
namespace webrtc {
namespace pcc {
namespace test {
namespace {
const DataRate kTargetSendingRate = DataRate::kbps(300);
const Timestamp kStartTime = Timestamp::us(0);
const TimeDelta kPacketsDelta = TimeDelta::ms(1);
const TimeDelta kIntervalDuration = TimeDelta::ms(100);
const TimeDelta kDefaultDelay = TimeDelta::ms(100);
const DataSize kDefaultPacketSize = DataSize::bytes(100);
constexpr double kDelayGradientThreshold = 0.01;
std::vector<PacketResult> CreatePacketResults(
const std::vector<Timestamp>& packets_send_times,
const std::vector<Timestamp>& packets_received_times = {},
const std::vector<DataSize>& packets_sizes = {}) {
std::vector<PacketResult> packet_results;
for (size_t i = 0; i < packets_send_times.size(); ++i) {
SentPacket sent_packet;
sent_packet.send_time = packets_send_times[i];
if (packets_sizes.empty()) {
sent_packet.size = kDefaultPacketSize;
} else {
sent_packet.size = packets_sizes[i];
}
PacketResult packet_result;
packet_result.sent_packet = sent_packet;
if (packets_received_times.empty()) {
packet_result.receive_time = packets_send_times[i] + kDefaultDelay;
} else {
packet_result.receive_time = packets_received_times[i];
}
packet_results.push_back(packet_result);
}
return packet_results;
}
} // namespace
TEST(PccMonitorIntervalTest, InitialValuesAreEqualToOnesSetInConstructor) {
PccMonitorInterval interval{kTargetSendingRate, kStartTime,
kIntervalDuration};
EXPECT_EQ(interval.IsFeedbackCollectionDone(), false);
EXPECT_EQ(interval.GetEndTime(), kStartTime + kIntervalDuration);
EXPECT_EQ(interval.GetTargetSendingRate(), kTargetSendingRate);
}
TEST(PccMonitorIntervalTest, IndicatesDoneWhenFeedbackReceivedAfterInterval) {
PccMonitorInterval interval{kTargetSendingRate, kStartTime,
kIntervalDuration};
interval.OnPacketsFeedback(CreatePacketResults({kStartTime}));
EXPECT_EQ(interval.IsFeedbackCollectionDone(), false);
interval.OnPacketsFeedback(
CreatePacketResults({kStartTime, kStartTime + kIntervalDuration}));
EXPECT_EQ(interval.IsFeedbackCollectionDone(), false);
interval.OnPacketsFeedback(CreatePacketResults(
{kStartTime + kIntervalDuration, kStartTime + 2 * kIntervalDuration}));
EXPECT_EQ(interval.IsFeedbackCollectionDone(), true);
}
TEST(PccMonitorIntervalTest, LossRateIsOneThirdIfLostOnePacketOutOfThree) {
PccMonitorInterval interval{kTargetSendingRate, kStartTime,
kIntervalDuration};
std::vector<Timestamp> start_times = {
kStartTime, kStartTime + 0.1 * kIntervalDuration,
kStartTime + 0.5 * kIntervalDuration, kStartTime + kIntervalDuration,
kStartTime + 2 * kIntervalDuration};
std::vector<Timestamp> end_times = {
kStartTime + 2 * kIntervalDuration, kStartTime + 2 * kIntervalDuration,
Timestamp::PlusInfinity(), kStartTime + 2 * kIntervalDuration,
kStartTime + 4 * kIntervalDuration};
std::vector<DataSize> packet_sizes = {
kDefaultPacketSize, 2 * kDefaultPacketSize, 3 * kDefaultPacketSize,
4 * kDefaultPacketSize, 5 * kDefaultPacketSize};
std::vector<PacketResult> packet_results =
CreatePacketResults(start_times, end_times, packet_sizes);
interval.OnPacketsFeedback(packet_results);
EXPECT_EQ(interval.IsFeedbackCollectionDone(), true);
EXPECT_DOUBLE_EQ(interval.GetLossRate(), 1. / 3);
}
TEST(PccMonitorIntervalTest, DelayGradientIsZeroIfNoChangeInPacketDelay) {
PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
kIntervalDuration);
monitor_interval.OnPacketsFeedback(CreatePacketResults(
{kStartTime + kPacketsDelta, kStartTime + 2 * kPacketsDelta,
kStartTime + 3 * kPacketsDelta, kStartTime + 2 * kIntervalDuration},
{kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
kStartTime + kDefaultDelay + 2 * kPacketsDelta,
Timestamp::PlusInfinity()},
{}));
// Delay gradient should be zero, because both received packets have the
// same one way delay.
EXPECT_DOUBLE_EQ(
monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 0);
}
TEST(PccMonitorIntervalTest,
DelayGradientIsZeroWhenOnePacketSentInMonitorInterval) {
PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
kIntervalDuration);
monitor_interval.OnPacketsFeedback(CreatePacketResults(
{kStartTime + kPacketsDelta, kStartTime + 2 * kIntervalDuration},
{kStartTime + kDefaultDelay, kStartTime + 3 * kIntervalDuration}, {}));
// Only one received packet belongs to the monitor_interval, delay gradient
// should be zero in this case.
EXPECT_DOUBLE_EQ(
monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 0);
}
TEST(PccMonitorIntervalTest, DelayGradientIsOne) {
PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
kIntervalDuration);
monitor_interval.OnPacketsFeedback(CreatePacketResults(
{kStartTime + kPacketsDelta, kStartTime + 2 * kPacketsDelta,
kStartTime + 3 * kPacketsDelta, kStartTime + 3 * kIntervalDuration},
{kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
kStartTime + 4 * kPacketsDelta + kDefaultDelay,
kStartTime + 3 * kIntervalDuration},
{}));
EXPECT_DOUBLE_EQ(
monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 1);
}
TEST(PccMonitorIntervalTest, DelayGradientIsMinusOne) {
PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
kIntervalDuration);
monitor_interval.OnPacketsFeedback(CreatePacketResults(
{kStartTime + kPacketsDelta, kStartTime + 2 * kPacketsDelta,
kStartTime + 5 * kPacketsDelta, kStartTime + 2 * kIntervalDuration},
{kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
kStartTime + kDefaultDelay, kStartTime + 3 * kIntervalDuration},
{}));
EXPECT_DOUBLE_EQ(
monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), -1);
}
TEST(PccMonitorIntervalTest,
DelayGradientIsZeroIfItSmallerWhenGradientThreshold) {
PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
kIntervalDuration);
monitor_interval.OnPacketsFeedback(CreatePacketResults(
{kStartTime + kPacketsDelta, kStartTime + kPacketsDelta,
kStartTime + 102 * kPacketsDelta, kStartTime + 2 * kIntervalDuration},
{kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
kStartTime + kDefaultDelay + kPacketsDelta,
kStartTime + 3 * kIntervalDuration},
{}));
// Delay gradient is less than 0.01 hence should be treated as zero.
EXPECT_DOUBLE_EQ(
monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 0);
}
TEST(PccMonitorIntervalTest,
DelayGradientIsZeroWhenAllPacketsSentAtTheSameTime) {
PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
kIntervalDuration);
monitor_interval.OnPacketsFeedback(CreatePacketResults(
{kStartTime + kPacketsDelta, kStartTime + kPacketsDelta,
kStartTime + kPacketsDelta, kStartTime + 2 * kIntervalDuration},
{kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
kStartTime + kDefaultDelay + kPacketsDelta,
kStartTime + 3 * kIntervalDuration},
{}));
// If all packets were sent at the same time, then delay gradient should be
// zero.
EXPECT_DOUBLE_EQ(
monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 0);
}
} // namespace test
} // namespace pcc
} // namespace webrtc