blob: 927015615c1708299464fe355bd0b72629107701 [file] [log] [blame]
isheriff31687812016-10-04 08:43:09 -07001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/pacing/alr_detector.h"
isheriff31687812016-10-04 08:43:09 -070012
Erik Språngb378a222017-10-02 13:25:38 +020013#include "test/field_trial.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "test/gtest.h"
Sergey Ulanov0182f852016-11-16 15:42:11 -080015
isheriff31687812016-10-04 08:43:09 -070016namespace {
17
isheriff31687812016-10-04 08:43:09 -070018constexpr int kEstimatedBitrateBps = 300000;
isheriff31687812016-10-04 08:43:09 -070019
20} // namespace
21
22namespace webrtc {
23
tschumim82c55932017-07-11 06:56:04 -070024namespace {
25class SimulateOutgoingTrafficIn {
26 public:
27 explicit SimulateOutgoingTrafficIn(AlrDetector* alr_detector)
28 : alr_detector_(alr_detector) {
29 RTC_CHECK(alr_detector_);
30 }
31
32 SimulateOutgoingTrafficIn& ForTimeMs(int time_ms) {
33 interval_ms_ = rtc::Optional<int>(time_ms);
34 interval_ms_.emplace(time_ms);
35 ProduceTraffic();
36 return *this;
37 }
38
39 SimulateOutgoingTrafficIn& AtPercentOfEstimatedBitrate(int usage_percentage) {
40 usage_percentage_.emplace(usage_percentage);
41 ProduceTraffic();
42 return *this;
43 }
44
45 private:
46 void ProduceTraffic() {
47 if (!interval_ms_ || !usage_percentage_)
48 return;
49 const int kTimeStepMs = 10;
50 for (int t = 0; t < *interval_ms_; t += kTimeStepMs) {
51 alr_detector_->OnBytesSent(kEstimatedBitrateBps * *usage_percentage_ *
52 kTimeStepMs / (8 * 100 * 1000),
53 kTimeStepMs);
54 }
55 int remainder_ms = *interval_ms_ % kTimeStepMs;
56 if (remainder_ms > 0) {
57 alr_detector_->OnBytesSent(kEstimatedBitrateBps * *usage_percentage_ *
58 remainder_ms / (8 * 100 * 1000),
59 kTimeStepMs);
60 }
61 }
62 AlrDetector* const alr_detector_;
63 rtc::Optional<int> interval_ms_;
64 rtc::Optional<int> usage_percentage_;
65};
66} // namespace
67
Sergey Ulanov0182f852016-11-16 15:42:11 -080068class AlrDetectorTest : public testing::Test {
69 public:
70 void SetUp() override {
71 alr_detector_.SetEstimatedBitrate(kEstimatedBitrateBps);
72 }
isheriff31687812016-10-04 08:43:09 -070073
Sergey Ulanov0182f852016-11-16 15:42:11 -080074 protected:
75 AlrDetector alr_detector_;
Sergey Ulanov0182f852016-11-16 15:42:11 -080076};
77
78TEST_F(AlrDetectorTest, AlrDetection) {
79 // Start in non-ALR state.
sergeyu80ed35e2016-11-28 13:11:13 -080080 EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime());
Sergey Ulanov0182f852016-11-16 15:42:11 -080081
82 // Stay in non-ALR state when usage is close to 100%.
tschumim82c55932017-07-11 06:56:04 -070083 SimulateOutgoingTrafficIn(&alr_detector_)
84 .ForTimeMs(1000)
85 .AtPercentOfEstimatedBitrate(90);
sergeyu80ed35e2016-11-28 13:11:13 -080086 EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime());
Sergey Ulanov0182f852016-11-16 15:42:11 -080087
88 // Verify that we ALR starts when bitrate drops below 20%.
tschumim82c55932017-07-11 06:56:04 -070089 SimulateOutgoingTrafficIn(&alr_detector_)
tschumim9d117642017-07-17 01:41:41 -070090 .ForTimeMs(1500)
tschumim82c55932017-07-11 06:56:04 -070091 .AtPercentOfEstimatedBitrate(20);
sergeyu80ed35e2016-11-28 13:11:13 -080092 EXPECT_TRUE(alr_detector_.GetApplicationLimitedRegionStartTime());
Sergey Ulanov0182f852016-11-16 15:42:11 -080093
tschumim82c55932017-07-11 06:56:04 -070094 // Verify that ALR ends when usage is above 65%.
95 SimulateOutgoingTrafficIn(&alr_detector_)
96 .ForTimeMs(1000)
97 .AtPercentOfEstimatedBitrate(100);
sergeyu80ed35e2016-11-28 13:11:13 -080098 EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime());
isheriff31687812016-10-04 08:43:09 -070099}
100
Sergey Ulanov0182f852016-11-16 15:42:11 -0800101TEST_F(AlrDetectorTest, ShortSpike) {
102 // Start in non-ALR state.
sergeyu80ed35e2016-11-28 13:11:13 -0800103 EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime());
isheriff31687812016-10-04 08:43:09 -0700104
Sergey Ulanov0182f852016-11-16 15:42:11 -0800105 // Verify that we ALR starts when bitrate drops below 20%.
tschumim82c55932017-07-11 06:56:04 -0700106 SimulateOutgoingTrafficIn(&alr_detector_)
107 .ForTimeMs(1000)
108 .AtPercentOfEstimatedBitrate(20);
sergeyu80ed35e2016-11-28 13:11:13 -0800109 EXPECT_TRUE(alr_detector_.GetApplicationLimitedRegionStartTime());
Sergey Ulanov0182f852016-11-16 15:42:11 -0800110
111 // Verify that we stay in ALR region even after a short bitrate spike.
tschumim82c55932017-07-11 06:56:04 -0700112 SimulateOutgoingTrafficIn(&alr_detector_)
tschumim9d117642017-07-17 01:41:41 -0700113 .ForTimeMs(100)
tschumim82c55932017-07-11 06:56:04 -0700114 .AtPercentOfEstimatedBitrate(150);
sergeyu80ed35e2016-11-28 13:11:13 -0800115 EXPECT_TRUE(alr_detector_.GetApplicationLimitedRegionStartTime());
Sergey Ulanov0182f852016-11-16 15:42:11 -0800116
tschumim82c55932017-07-11 06:56:04 -0700117 // ALR ends when usage is above 65%.
118 SimulateOutgoingTrafficIn(&alr_detector_)
119 .ForTimeMs(1000)
120 .AtPercentOfEstimatedBitrate(100);
sergeyu80ed35e2016-11-28 13:11:13 -0800121 EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime());
Sergey Ulanov0182f852016-11-16 15:42:11 -0800122}
123
124TEST_F(AlrDetectorTest, BandwidthEstimateChanges) {
125 // Start in non-ALR state.
sergeyu80ed35e2016-11-28 13:11:13 -0800126 EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime());
Sergey Ulanov0182f852016-11-16 15:42:11 -0800127
128 // ALR starts when bitrate drops below 20%.
tschumim82c55932017-07-11 06:56:04 -0700129 SimulateOutgoingTrafficIn(&alr_detector_)
130 .ForTimeMs(1000)
131 .AtPercentOfEstimatedBitrate(20);
sergeyu80ed35e2016-11-28 13:11:13 -0800132 EXPECT_TRUE(alr_detector_.GetApplicationLimitedRegionStartTime());
Sergey Ulanov0182f852016-11-16 15:42:11 -0800133
134 // When bandwidth estimate drops the detector should stay in ALR mode and quit
135 // it shortly afterwards as the sender continues sending the same amount of
136 // traffic. This is necessary to ensure that ProbeController can still react
137 // to the BWE drop by initiating a new probe.
138 alr_detector_.SetEstimatedBitrate(kEstimatedBitrateBps / 5);
sergeyu80ed35e2016-11-28 13:11:13 -0800139 EXPECT_TRUE(alr_detector_.GetApplicationLimitedRegionStartTime());
tschumim82c55932017-07-11 06:56:04 -0700140 SimulateOutgoingTrafficIn(&alr_detector_)
141 .ForTimeMs(1000)
142 .AtPercentOfEstimatedBitrate(50);
sergeyu80ed35e2016-11-28 13:11:13 -0800143 EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime());
isheriff31687812016-10-04 08:43:09 -0700144}
145
Erik Språngb378a222017-10-02 13:25:38 +0200146TEST_F(AlrDetectorTest, ParseControlFieldTrial) {
147 webrtc::test::ScopedFieldTrials field_trial(
148 "WebRTC-ProbingScreenshareBwe/Control/");
149 rtc::Optional<AlrDetector::AlrExperimentSettings> parsed_params =
150 AlrDetector::ParseAlrSettingsFromFieldTrial(
151 "WebRTC-ProbingScreenshareBwe");
152 EXPECT_FALSE(static_cast<bool>(parsed_params));
153}
154
155TEST_F(AlrDetectorTest, ParseActiveFieldTrial) {
156 webrtc::test::ScopedFieldTrials field_trial(
157 "WebRTC-ProbingScreenshareBwe/1.1,2875,85,20,-20,1/");
158 rtc::Optional<AlrDetector::AlrExperimentSettings> parsed_params =
159 AlrDetector::ParseAlrSettingsFromFieldTrial(
160 "WebRTC-ProbingScreenshareBwe");
161 ASSERT_TRUE(static_cast<bool>(parsed_params));
162 EXPECT_EQ(1.1f, parsed_params->pacing_factor);
163 EXPECT_EQ(2875, parsed_params->max_paced_queue_time);
164 EXPECT_EQ(85, parsed_params->alr_bandwidth_usage_percent);
165 EXPECT_EQ(20, parsed_params->alr_start_budget_level_percent);
166 EXPECT_EQ(-20, parsed_params->alr_stop_budget_level_percent);
167 EXPECT_EQ(1, parsed_params->group_id);
168}
169
isheriff31687812016-10-04 08:43:09 -0700170} // namespace webrtc