1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 
18 #include <thread>
19 #include <climits>
20 
21 
22 #define private public
23 #define protect public
24 #include "sched/interval.h"
25 #include "sched/frame_interval.h"
26 #include "sched/load_tracking.h"
27 #undef private
28 #undef protect
29 #include "../common.h"
30 
31 using namespace testing;
32 #ifdef HWTEST_TESTING_EXT_ENABLE
33 using namespace testing::ext;
34 #endif
35 using namespace ffrt;
36 
37 class IntervalTest : public testing::Test {
38 protected:
SetUpTestCase()39     static void SetUpTestCase()
40     {
41     }
42 
TearDownTestCase()43     static void TearDownTestCase()
44     {
45     }
46 
SetUp()47     virtual void SetUp()
48     {
49     }
50 
TearDown()51     virtual void TearDown()
52     {
53     }
54 };
55 
56 HWTEST_F(IntervalTest, deadline_test, TestSize.Level1)
57 {
58     Deadline dl(0);
59     EXPECT_EQ(dl.ToNs(), 1);
60     EXPECT_EQ(dl.ToUs(), 1);
61     EXPECT_EQ(dl.ToMs(), 1);
62 
63     dl.Update(1000);
64     EXPECT_EQ(dl.ToNs(), 1000000);
65     EXPECT_EQ(dl.ToUs(), 1000);
66     EXPECT_EQ(dl.ToMs(), 1);
67 
68     dl.Update(1000000);
69     EXPECT_NE(dl.LeftNs(), 1);
70 
71     std::this_thread::sleep_for(std::chrono::milliseconds(1001));
72 
73     EXPECT_EQ(dl.LeftNs(), 1);
74 }
75 
76 HWTEST_F(IntervalTest, simple_load_predictor_test, TestSize.Level1)
77 {
78     std::initializer_list<std::pair<int, int>> table = {
79         {10, 10},
80         {100, 100},
81         {300, 300},
82         {50, 300},
83         {3000, 3000},
84         {900, 3000},
85         {30, 900},
86         {200, 836},
87         {0, 826},
88         {5000, 5000},
89         {10240, 10240},
90         {25600, 25600},
91         {40, 25600},
92         {300, 8236},
93         {50, 7246},
94     };
95 
96     SimpleLoadPredictor lp;
97     for (auto& it : table) {
98         lp.UpdateLoad(it.first);
99         EXPECT_EQ(lp.GetPredictLoad(), it.second);
100     }
101 
102     lp.Clear();
103     EXPECT_EQ(lp.GetPredictLoad(), 0);
104 }
105 
106 HWTEST_F(IntervalTest, interval_basic_test, TestSize.Level1)
107 {
108     DefaultInterval interval = DefaultInterval(100, QoS(static_cast<int>(qos_deadline_request)));
109     int ret = interval.Begin();
110     EXPECT_EQ(ret, 0);
111     interval.End();
112 
113     ret = interval.Begin();
114     interval.Update(50);
115 
116     EXPECT_EQ(ret, 0);
117     usleep(10);
118     interval.CheckPoint();
119     interval.End();
120 }
121 
122 HWTEST_F(IntervalTest, interval_join_test, TestSize.Level1)
123 {
124     DefaultInterval interval = DefaultInterval(100, QoS(static_cast<int>(qos_deadline_request)));
125     int ret = interval.Begin();
126     EXPECT_EQ(ret, 0);
127 
128     interval.Join();
129     interval.Leave();
130 
131     interval.End();
132 }
133 
134 HWTEST_F(IntervalTest, interval_exception_test, TestSize.Level1)
135 {
136     // case interval begin while last interval not end
137     DefaultInterval interval = DefaultInterval(100, QoS(static_cast<int>(qos_deadline_request)));
138     int ret = interval.Begin();
139     EXPECT_EQ(ret, 0);
140     ret = interval.Begin();
141     EXPECT_EQ(ret, -1);
142     interval.End();
143     ret = interval.Begin();
144     EXPECT_EQ(ret, 0);
145     interval.End();
146 }
147 
148 HWTEST_F(IntervalTest, interval_exception2_test, TestSize.Level1)
149 {
150     // case interval function called before begin
151     DefaultInterval interval = DefaultInterval(100, QoS(static_cast<int>(qos_deadline_request)));
152 
153     interval.Update(50);
154     interval.CheckPoint();
155     interval.End();
156 
157     int ret = interval.Begin();
158     EXPECT_EQ(ret, 0);
159     interval.End();
160 }
161 
162 HWTEST_F(IntervalTest, fInterval_basic_test, TestSize.Level1)
163 {
164     FrameInterval interval = FrameInterval(100, QoS(static_cast<int>(qos_user_interactive)));
165     int ret = interval.Begin();
166     EXPECT_EQ(ret, 0);
167     interval.End();
168 
169     ret = interval.Begin();
170     interval.Update(50);
171 
172     EXPECT_EQ(ret, 0);
173     usleep(10);
174     interval.CheckPoint();
175     interval.End();
176 }
177 
178 HWTEST_F(IntervalTest, fInterval_join_test, TestSize.Level1)
179 {
180     FrameInterval interval = FrameInterval(100, QoS(static_cast<int>(qos_user_interactive)));
181     int ret = interval.Begin();
182     EXPECT_EQ(ret, 0);
183 
184     interval.Join();
185     interval.Leave();
186 
187     interval.End();
188 }
189 
190 HWTEST_F(IntervalTest, fInterval_exception_test, TestSize.Level1)
191 {
192     // case interval begin while last interval not end
193     FrameInterval interval = FrameInterval(100, QoS(static_cast<int>(qos_user_interactive)));
194     int ret = interval.Begin();
195     EXPECT_EQ(ret, 0);
196     ret = interval.Begin();
197     EXPECT_EQ(ret, -1);
198     interval.End();
199     ret = interval.Begin();
200     EXPECT_EQ(ret, 0);
201     interval.End();
202 }
203 
204 HWTEST_F(IntervalTest, fInterval_exception2_test, TestSize.Level1)
205 {
206     // case interval function called before begin
207     FrameInterval interval = FrameInterval(100, QoS(static_cast<int>(qos_user_interactive)));
208 
209     interval.Update(50);
210     interval.CheckPoint();
211     interval.End();
212 
213     int ret = interval.Begin();
214     EXPECT_EQ(ret, 0);
215     interval.End();
216 }
217 
218 HWTEST_F(IntervalTest, perfctrl_overload_test, TestSize.Level1)
219 {
220     PerfCtrl ctrl = PerfCtrl(QoS(static_cast<int>(qos_deadline_request)));
221     ctrl.Begin();
222     ctrl.Update(100, UINT_MAX, false);
223     ctrl.End();
224 }
225 
226 HWTEST_F(IntervalTest, perfctrl_invalid_qos_test, TestSize.Level1)
227 {
228     PerfCtrl ctrl = PerfCtrl(QoS(static_cast<int>(qos_inherit)));
229     ctrl.Begin();
230     ctrl.Update(100, 500, false);
231     ctrl.End();
232 }
233 
234 HWTEST_F(IntervalTest, loadPredict_basic_test, TestSize.Level1)
235 {
236     IntervalLoadPredictor lp;
237 
238     lp.UpdateTotalLoad(100);
239     lp.UpdateTotalLoad(200);
240     lp.UpdateTotalLoad(300);
241 
242     uint64_t load = lp.GetTotalLoad();
243     // max among average and recent 2 load
244     EXPECT_EQ(load, 300);
245 }