#include "common.hpp"
#include "RTC/RateCalculator.hpp"
#include <catch2/catch_test_macros.hpp>
#include <limits>
#include <vector>
SCENARIO("RateCalculator", "[rate-calculator]")
{
struct TestRateCalculatorData
{
int64_t offset;
uint32_t size;
uint32_t rate;
};
auto validate =
[](RTC::RateCalculator& rate, uint64_t timeBaseMs, std::vector<TestRateCalculatorData>& input)
{
for (auto& item : input)
{
rate.Update(item.size, timeBaseMs + item.offset);
REQUIRE(rate.GetRate(timeBaseMs + item.offset) == item.rate);
}
rate.Reset();
for (auto& item : input)
{
rate.Update(item.size, timeBaseMs + item.offset);
REQUIRE(rate.GetRate(0 + item.offset) == item.rate);
}
rate.Reset();
for (auto& item : input)
{
rate.Update(item.size, timeBaseMs + item.offset);
REQUIRE(rate.GetRate(std::numeric_limits<uint64_t>::max() - 100 + item.offset) == item.rate);
}
};
const uint64_t nowMs = 12345678;
SECTION("receive single item per 1000 ms")
{
RTC::RateCalculator rate;
std::vector<TestRateCalculatorData> input =
{
{ 0, 5, 40 }
};
validate(rate, nowMs, input);
}
SECTION("receive multiple items per 1000 ms")
{
RTC::RateCalculator rate;
std::vector<TestRateCalculatorData> input =
{
{ 0, 5, 40 },
{ 100, 2, 56 },
{ 300, 2, 72 },
{ 999, 4, 104 }
};
validate(rate, nowMs, input);
}
SECTION("receive item every 1000 ms")
{
RTC::RateCalculator rate(1000, 8000, 100);
std::vector<TestRateCalculatorData> input =
{
{ 0, 5, 40 },
{ 1000, 5, 40 },
{ 2000, 5, 40 }
};
validate(rate, nowMs, input);
}
SECTION("slide")
{
RTC::RateCalculator rate(1000, 8000, 1000);
std::vector<TestRateCalculatorData> input =
{
{ 0, 5, 40 },
{ 999, 2, 56 },
{ 1001, 1, 24 },
{ 1001, 1, 32 },
{ 2000, 1, 24 }
};
validate(rate, nowMs, input);
REQUIRE(rate.GetRate(nowMs + 3001) == 0);
}
SECTION("slide with 100 items")
{
RTC::RateCalculator rate(1000, 8000, 100);
std::vector<TestRateCalculatorData> input =
{
{ 0, 5, 40 },
{ 999, 2, 56 },
{ 1001, 1, 24 }, { 1001, 1, 32 }, { 2000, 1, 8 } };
validate(rate, nowMs, input);
REQUIRE(rate.GetRate(nowMs + 3001) == 0);
}
SECTION("wrap")
{
RTC::RateCalculator rate(1000, 8000, 5);
std::vector<TestRateCalculatorData> input =
{
{ 1000, 1, 1*8 },
{ 1200, 1, 1*8 + 1*8 },
{ 1400, 1, 1*8 + 2*8 },
{ 1600, 1, 1*8 + 3*8 },
{ 1800, 1, 1*8 + 4*8 },
{ 2000, 1, 1*8 + (5-1)*8 }, { 2200, 1, 1*8 + (6-2)*8 },
{ 2400, 1, 1*8 + (7-3)*8 },
{ 2600, 1, 1*8 + (8-4)*8 },
{ 2800, 1, 1*8 + (9-5)*8 },
};
validate(rate, nowMs, input);
}
SECTION("buffer overflow should not crash")
{
RTC::RateCalculator rate(1000, 8000, 3);
std::vector<TestRateCalculatorData> input =
{
{ 0, 1, 8 },
{ 333, 1, 16 },
{ 666, 1, 24 },
{ 999, 1, 32 },
};
validate(rate, nowMs, input);
}
}