1 /*
2  *  Copyright 2019 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 "video/quality_limitation_reason_tracker.h"
12 
13 #include "common_video/include/quality_limitation_reason.h"
14 #include "system_wrappers/include/clock.h"
15 #include "test/gtest.h"
16 
17 namespace webrtc {
18 
19 class QualityLimitationReasonTrackerTest : public ::testing::Test {
20  public:
QualityLimitationReasonTrackerTest()21   QualityLimitationReasonTrackerTest()
22       : fake_clock_(1234), tracker_(&fake_clock_) {}
23 
24  protected:
25   SimulatedClock fake_clock_;
26   QualityLimitationReasonTracker tracker_;
27 };
28 
TEST_F(QualityLimitationReasonTrackerTest,DefaultValues)29 TEST_F(QualityLimitationReasonTrackerTest, DefaultValues) {
30   EXPECT_EQ(QualityLimitationReason::kNone, tracker_.current_reason());
31   auto durations_ms = tracker_.DurationsMs();
32   EXPECT_EQ(4u, durations_ms.size());
33   EXPECT_EQ(0, durations_ms.find(QualityLimitationReason::kNone)->second);
34   EXPECT_EQ(0, durations_ms.find(QualityLimitationReason::kCpu)->second);
35   EXPECT_EQ(0, durations_ms.find(QualityLimitationReason::kBandwidth)->second);
36   EXPECT_EQ(0, durations_ms.find(QualityLimitationReason::kOther)->second);
37 }
38 
TEST_F(QualityLimitationReasonTrackerTest,NoneDurationIncreasesByDefault)39 TEST_F(QualityLimitationReasonTrackerTest, NoneDurationIncreasesByDefault) {
40   int64_t initial_duration_ms =
41       tracker_.DurationsMs()[QualityLimitationReason::kNone];
42   fake_clock_.AdvanceTimeMilliseconds(9999);
43   EXPECT_EQ(initial_duration_ms + 9999,
44             tracker_.DurationsMs()[QualityLimitationReason::kNone]);
45 }
46 
TEST_F(QualityLimitationReasonTrackerTest,RememberDurationAfterSwitchingReason)47 TEST_F(QualityLimitationReasonTrackerTest,
48        RememberDurationAfterSwitchingReason) {
49   tracker_.SetReason(QualityLimitationReason::kCpu);
50   int64_t initial_duration_ms =
51       tracker_.DurationsMs()[QualityLimitationReason::kCpu];
52   fake_clock_.AdvanceTimeMilliseconds(50);
53   tracker_.SetReason(QualityLimitationReason::kOther);
54   fake_clock_.AdvanceTimeMilliseconds(50);
55   EXPECT_EQ(initial_duration_ms + 50,
56             tracker_.DurationsMs()[QualityLimitationReason::kCpu]);
57 }
58 
59 class QualityLimitationReasonTrackerTestWithParamReason
60     : public QualityLimitationReasonTrackerTest,
61       public ::testing::WithParamInterface<QualityLimitationReason> {
62  public:
QualityLimitationReasonTrackerTestWithParamReason()63   QualityLimitationReasonTrackerTestWithParamReason()
64       : reason_(GetParam()),
65         different_reason_(reason_ != QualityLimitationReason::kCpu
66                               ? QualityLimitationReason::kCpu
67                               : QualityLimitationReason::kOther) {}
68 
69  protected:
70   QualityLimitationReason reason_;
71   QualityLimitationReason different_reason_;
72 };
73 
TEST_P(QualityLimitationReasonTrackerTestWithParamReason,DurationIncreasesOverTime)74 TEST_P(QualityLimitationReasonTrackerTestWithParamReason,
75        DurationIncreasesOverTime) {
76   int64_t initial_duration_ms = tracker_.DurationsMs()[reason_];
77   tracker_.SetReason(reason_);
78   EXPECT_EQ(initial_duration_ms, tracker_.DurationsMs()[reason_]);
79   fake_clock_.AdvanceTimeMilliseconds(4321);
80   EXPECT_EQ(initial_duration_ms + 4321, tracker_.DurationsMs()[reason_]);
81 }
82 
TEST_P(QualityLimitationReasonTrackerTestWithParamReason,SwitchBetweenReasonsBackAndForth)83 TEST_P(QualityLimitationReasonTrackerTestWithParamReason,
84        SwitchBetweenReasonsBackAndForth) {
85   int64_t initial_duration_ms = tracker_.DurationsMs()[reason_];
86   // Spend 100 ms in |different_reason_|.
87   tracker_.SetReason(different_reason_);
88   fake_clock_.AdvanceTimeMilliseconds(100);
89   EXPECT_EQ(initial_duration_ms, tracker_.DurationsMs()[reason_]);
90   // Spend 50 ms in |reason_|.
91   tracker_.SetReason(reason_);
92   fake_clock_.AdvanceTimeMilliseconds(50);
93   EXPECT_EQ(initial_duration_ms + 50, tracker_.DurationsMs()[reason_]);
94   // Spend another 1000 ms in |different_reason_|.
95   tracker_.SetReason(different_reason_);
96   fake_clock_.AdvanceTimeMilliseconds(1000);
97   EXPECT_EQ(initial_duration_ms + 50, tracker_.DurationsMs()[reason_]);
98   // Spend another 100 ms in |reason_|.
99   tracker_.SetReason(reason_);
100   fake_clock_.AdvanceTimeMilliseconds(100);
101   EXPECT_EQ(initial_duration_ms + 150, tracker_.DurationsMs()[reason_]);
102   // Change reason one last time without advancing time.
103   tracker_.SetReason(different_reason_);
104   EXPECT_EQ(initial_duration_ms + 150, tracker_.DurationsMs()[reason_]);
105 }
106 
107 INSTANTIATE_TEST_SUITE_P(
108     All,
109     QualityLimitationReasonTrackerTestWithParamReason,
110     ::testing::Values(QualityLimitationReason::kNone,       // "/0"
111                       QualityLimitationReason::kCpu,        // "/1"
112                       QualityLimitationReason::kBandwidth,  // "/2"
113                       QualityLimitationReason::kOther));    // "/3"
114 
115 }  // namespace webrtc
116