1 /*
2 * Copyright (c) 2016 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/pacing/interval_budget.h"
12
13 #include "test/gtest.h"
14
15 namespace webrtc {
16
17 namespace {
18 constexpr int kWindowMs = 500;
19 constexpr int kBitrateKbps = 100;
20 constexpr bool kCanBuildUpUnderuse = true;
21 constexpr bool kCanNotBuildUpUnderuse = false;
TimeToBytes(int bitrate_kbps,int time_ms)22 size_t TimeToBytes(int bitrate_kbps, int time_ms) {
23 return static_cast<size_t>(bitrate_kbps * time_ms / 8);
24 }
25 } // namespace
26
TEST(IntervalBudgetTest,InitailState)27 TEST(IntervalBudgetTest, InitailState) {
28 IntervalBudget interval_budget(kBitrateKbps);
29 EXPECT_DOUBLE_EQ(interval_budget.budget_ratio(), 0.0);
30 EXPECT_EQ(interval_budget.bytes_remaining(), 0u);
31 }
32
TEST(IntervalBudgetTest,Underuse)33 TEST(IntervalBudgetTest, Underuse) {
34 IntervalBudget interval_budget(kBitrateKbps);
35 int delta_time_ms = 50;
36 interval_budget.IncreaseBudget(delta_time_ms);
37 EXPECT_DOUBLE_EQ(interval_budget.budget_ratio(),
38 kWindowMs / static_cast<double>(100 * delta_time_ms));
39 EXPECT_EQ(interval_budget.bytes_remaining(),
40 TimeToBytes(kBitrateKbps, delta_time_ms));
41 }
42
TEST(IntervalBudgetTest,DontUnderuseMoreThanMaxWindow)43 TEST(IntervalBudgetTest, DontUnderuseMoreThanMaxWindow) {
44 IntervalBudget interval_budget(kBitrateKbps);
45 int delta_time_ms = 1000;
46 interval_budget.IncreaseBudget(delta_time_ms);
47 EXPECT_DOUBLE_EQ(interval_budget.budget_ratio(), 1.0);
48 EXPECT_EQ(interval_budget.bytes_remaining(),
49 TimeToBytes(kBitrateKbps, kWindowMs));
50 }
51
TEST(IntervalBudgetTest,DontUnderuseMoreThanMaxWindowWhenChangeBitrate)52 TEST(IntervalBudgetTest, DontUnderuseMoreThanMaxWindowWhenChangeBitrate) {
53 IntervalBudget interval_budget(kBitrateKbps);
54 int delta_time_ms = kWindowMs / 2;
55 interval_budget.IncreaseBudget(delta_time_ms);
56 interval_budget.set_target_rate_kbps(kBitrateKbps / 10);
57 EXPECT_DOUBLE_EQ(interval_budget.budget_ratio(), 1.0);
58 EXPECT_EQ(interval_budget.bytes_remaining(),
59 TimeToBytes(kBitrateKbps / 10, kWindowMs));
60 }
61
TEST(IntervalBudgetTest,BalanceChangeOnBitrateChange)62 TEST(IntervalBudgetTest, BalanceChangeOnBitrateChange) {
63 IntervalBudget interval_budget(kBitrateKbps);
64 int delta_time_ms = kWindowMs;
65 interval_budget.IncreaseBudget(delta_time_ms);
66 interval_budget.set_target_rate_kbps(kBitrateKbps * 2);
67 EXPECT_DOUBLE_EQ(interval_budget.budget_ratio(), 0.5);
68 EXPECT_EQ(interval_budget.bytes_remaining(),
69 TimeToBytes(kBitrateKbps, kWindowMs));
70 }
71
TEST(IntervalBudgetTest,Overuse)72 TEST(IntervalBudgetTest, Overuse) {
73 IntervalBudget interval_budget(kBitrateKbps);
74 int overuse_time_ms = 50;
75 int used_bytes = TimeToBytes(kBitrateKbps, overuse_time_ms);
76 interval_budget.UseBudget(used_bytes);
77 EXPECT_DOUBLE_EQ(interval_budget.budget_ratio(),
78 -kWindowMs / static_cast<double>(100 * overuse_time_ms));
79 EXPECT_EQ(interval_budget.bytes_remaining(), 0u);
80 }
81
TEST(IntervalBudgetTest,DontOveruseMoreThanMaxWindow)82 TEST(IntervalBudgetTest, DontOveruseMoreThanMaxWindow) {
83 IntervalBudget interval_budget(kBitrateKbps);
84 int overuse_time_ms = 1000;
85 int used_bytes = TimeToBytes(kBitrateKbps, overuse_time_ms);
86 interval_budget.UseBudget(used_bytes);
87 EXPECT_DOUBLE_EQ(interval_budget.budget_ratio(), -1.0);
88 EXPECT_EQ(interval_budget.bytes_remaining(), 0u);
89 }
90
TEST(IntervalBudgetTest,CanBuildUpUnderuseWhenConfigured)91 TEST(IntervalBudgetTest, CanBuildUpUnderuseWhenConfigured) {
92 IntervalBudget interval_budget(kBitrateKbps, kCanBuildUpUnderuse);
93 int delta_time_ms = 50;
94 interval_budget.IncreaseBudget(delta_time_ms);
95 EXPECT_DOUBLE_EQ(interval_budget.budget_ratio(),
96 kWindowMs / static_cast<double>(100 * delta_time_ms));
97 EXPECT_EQ(interval_budget.bytes_remaining(),
98 TimeToBytes(kBitrateKbps, delta_time_ms));
99
100 interval_budget.IncreaseBudget(delta_time_ms);
101 EXPECT_DOUBLE_EQ(interval_budget.budget_ratio(),
102 2 * kWindowMs / static_cast<double>(100 * delta_time_ms));
103 EXPECT_EQ(interval_budget.bytes_remaining(),
104 TimeToBytes(kBitrateKbps, 2 * delta_time_ms));
105 }
106
TEST(IntervalBudgetTest,CanNotBuildUpUnderuseWhenConfigured)107 TEST(IntervalBudgetTest, CanNotBuildUpUnderuseWhenConfigured) {
108 IntervalBudget interval_budget(kBitrateKbps, kCanNotBuildUpUnderuse);
109 int delta_time_ms = 50;
110 interval_budget.IncreaseBudget(delta_time_ms);
111 EXPECT_DOUBLE_EQ(interval_budget.budget_ratio(),
112 kWindowMs / static_cast<double>(100 * delta_time_ms));
113 EXPECT_EQ(interval_budget.bytes_remaining(),
114 TimeToBytes(kBitrateKbps, delta_time_ms));
115
116 interval_budget.IncreaseBudget(delta_time_ms);
117 EXPECT_DOUBLE_EQ(interval_budget.budget_ratio(),
118 kWindowMs / static_cast<double>(100 * delta_time_ms));
119 EXPECT_EQ(interval_budget.bytes_remaining(),
120 TimeToBytes(kBitrateKbps, delta_time_ms));
121 }
122
123 } // namespace webrtc
124