/* * 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 #include "test/gtest.h" namespace webrtc { namespace pcc { namespace test { namespace { const DataRate kTargetSendingRate = DataRate::KilobitsPerSec(300); const Timestamp kStartTime = Timestamp::Micros(0); const TimeDelta kPacketsDelta = TimeDelta::Millis(1); const TimeDelta kIntervalDuration = TimeDelta::Millis(100); const TimeDelta kDefaultDelay = TimeDelta::Millis(100); const DataSize kDefaultPacketSize = DataSize::Bytes(100); constexpr double kDelayGradientThreshold = 0.01; std::vector CreatePacketResults( const std::vector& packets_send_times, const std::vector& packets_received_times = {}, const std::vector& packets_sizes = {}) { std::vector 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 start_times = { kStartTime, kStartTime + 0.1 * kIntervalDuration, kStartTime + 0.5 * kIntervalDuration, kStartTime + kIntervalDuration, kStartTime + 2 * kIntervalDuration}; std::vector end_times = { kStartTime + 2 * kIntervalDuration, kStartTime + 2 * kIntervalDuration, Timestamp::PlusInfinity(), kStartTime + 2 * kIntervalDuration, kStartTime + 4 * kIntervalDuration}; std::vector packet_sizes = { kDefaultPacketSize, 2 * kDefaultPacketSize, 3 * kDefaultPacketSize, 4 * kDefaultPacketSize, 5 * kDefaultPacketSize}; std::vector 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