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