1484543d1Sopenharmony_ci/*
2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License.
5484543d1Sopenharmony_ci * You may obtain a copy of the License at
6484543d1Sopenharmony_ci *
7484543d1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8484543d1Sopenharmony_ci *
9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and
13484543d1Sopenharmony_ci * limitations under the License.
14484543d1Sopenharmony_ci */
15484543d1Sopenharmony_ci
16484543d1Sopenharmony_ci#include <gtest/gtest.h>
17484543d1Sopenharmony_ci
18484543d1Sopenharmony_ci#include <thread>
19484543d1Sopenharmony_ci#include <climits>
20484543d1Sopenharmony_ci
21484543d1Sopenharmony_ci
22484543d1Sopenharmony_ci#define private public
23484543d1Sopenharmony_ci#define protect public
24484543d1Sopenharmony_ci#include "sched/interval.h"
25484543d1Sopenharmony_ci#include "sched/frame_interval.h"
26484543d1Sopenharmony_ci#include "sched/load_tracking.h"
27484543d1Sopenharmony_ci#undef private
28484543d1Sopenharmony_ci#undef protect
29484543d1Sopenharmony_ci#include "../common.h"
30484543d1Sopenharmony_ci
31484543d1Sopenharmony_ciusing namespace testing;
32484543d1Sopenharmony_ci#ifdef HWTEST_TESTING_EXT_ENABLE
33484543d1Sopenharmony_ciusing namespace testing::ext;
34484543d1Sopenharmony_ci#endif
35484543d1Sopenharmony_ciusing namespace ffrt;
36484543d1Sopenharmony_ci
37484543d1Sopenharmony_ciclass IntervalTest : public testing::Test {
38484543d1Sopenharmony_ciprotected:
39484543d1Sopenharmony_ci    static void SetUpTestCase()
40484543d1Sopenharmony_ci    {
41484543d1Sopenharmony_ci    }
42484543d1Sopenharmony_ci
43484543d1Sopenharmony_ci    static void TearDownTestCase()
44484543d1Sopenharmony_ci    {
45484543d1Sopenharmony_ci    }
46484543d1Sopenharmony_ci
47484543d1Sopenharmony_ci    virtual void SetUp()
48484543d1Sopenharmony_ci    {
49484543d1Sopenharmony_ci    }
50484543d1Sopenharmony_ci
51484543d1Sopenharmony_ci    virtual void TearDown()
52484543d1Sopenharmony_ci    {
53484543d1Sopenharmony_ci    }
54484543d1Sopenharmony_ci};
55484543d1Sopenharmony_ci
56484543d1Sopenharmony_ciHWTEST_F(IntervalTest, deadline_test, TestSize.Level1)
57484543d1Sopenharmony_ci{
58484543d1Sopenharmony_ci    Deadline dl(0);
59484543d1Sopenharmony_ci    EXPECT_EQ(dl.ToNs(), 1);
60484543d1Sopenharmony_ci    EXPECT_EQ(dl.ToUs(), 1);
61484543d1Sopenharmony_ci    EXPECT_EQ(dl.ToMs(), 1);
62484543d1Sopenharmony_ci
63484543d1Sopenharmony_ci    dl.Update(1000);
64484543d1Sopenharmony_ci    EXPECT_EQ(dl.ToNs(), 1000000);
65484543d1Sopenharmony_ci    EXPECT_EQ(dl.ToUs(), 1000);
66484543d1Sopenharmony_ci    EXPECT_EQ(dl.ToMs(), 1);
67484543d1Sopenharmony_ci
68484543d1Sopenharmony_ci    dl.Update(1000000);
69484543d1Sopenharmony_ci    EXPECT_NE(dl.LeftNs(), 1);
70484543d1Sopenharmony_ci
71484543d1Sopenharmony_ci    std::this_thread::sleep_for(std::chrono::milliseconds(1001));
72484543d1Sopenharmony_ci
73484543d1Sopenharmony_ci    EXPECT_EQ(dl.LeftNs(), 1);
74484543d1Sopenharmony_ci}
75484543d1Sopenharmony_ci
76484543d1Sopenharmony_ciHWTEST_F(IntervalTest, simple_load_predictor_test, TestSize.Level1)
77484543d1Sopenharmony_ci{
78484543d1Sopenharmony_ci    std::initializer_list<std::pair<int, int>> table = {
79484543d1Sopenharmony_ci        {10, 10},
80484543d1Sopenharmony_ci        {100, 100},
81484543d1Sopenharmony_ci        {300, 300},
82484543d1Sopenharmony_ci        {50, 300},
83484543d1Sopenharmony_ci        {3000, 3000},
84484543d1Sopenharmony_ci        {900, 3000},
85484543d1Sopenharmony_ci        {30, 900},
86484543d1Sopenharmony_ci        {200, 836},
87484543d1Sopenharmony_ci        {0, 826},
88484543d1Sopenharmony_ci        {5000, 5000},
89484543d1Sopenharmony_ci        {10240, 10240},
90484543d1Sopenharmony_ci        {25600, 25600},
91484543d1Sopenharmony_ci        {40, 25600},
92484543d1Sopenharmony_ci        {300, 8236},
93484543d1Sopenharmony_ci        {50, 7246},
94484543d1Sopenharmony_ci    };
95484543d1Sopenharmony_ci
96484543d1Sopenharmony_ci    SimpleLoadPredictor lp;
97484543d1Sopenharmony_ci    for (auto& it : table) {
98484543d1Sopenharmony_ci        lp.UpdateLoad(it.first);
99484543d1Sopenharmony_ci        EXPECT_EQ(lp.GetPredictLoad(), it.second);
100484543d1Sopenharmony_ci    }
101484543d1Sopenharmony_ci
102484543d1Sopenharmony_ci    lp.Clear();
103484543d1Sopenharmony_ci    EXPECT_EQ(lp.GetPredictLoad(), 0);
104484543d1Sopenharmony_ci}
105484543d1Sopenharmony_ci
106484543d1Sopenharmony_ciHWTEST_F(IntervalTest, interval_basic_test, TestSize.Level1)
107484543d1Sopenharmony_ci{
108484543d1Sopenharmony_ci    DefaultInterval interval = DefaultInterval(100, QoS(static_cast<int>(qos_deadline_request)));
109484543d1Sopenharmony_ci    int ret = interval.Begin();
110484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
111484543d1Sopenharmony_ci    interval.End();
112484543d1Sopenharmony_ci
113484543d1Sopenharmony_ci    ret = interval.Begin();
114484543d1Sopenharmony_ci    interval.Update(50);
115484543d1Sopenharmony_ci
116484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
117484543d1Sopenharmony_ci    usleep(10);
118484543d1Sopenharmony_ci    interval.CheckPoint();
119484543d1Sopenharmony_ci    interval.End();
120484543d1Sopenharmony_ci}
121484543d1Sopenharmony_ci
122484543d1Sopenharmony_ciHWTEST_F(IntervalTest, interval_join_test, TestSize.Level1)
123484543d1Sopenharmony_ci{
124484543d1Sopenharmony_ci    DefaultInterval interval = DefaultInterval(100, QoS(static_cast<int>(qos_deadline_request)));
125484543d1Sopenharmony_ci    int ret = interval.Begin();
126484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
127484543d1Sopenharmony_ci
128484543d1Sopenharmony_ci    interval.Join();
129484543d1Sopenharmony_ci    interval.Leave();
130484543d1Sopenharmony_ci
131484543d1Sopenharmony_ci    interval.End();
132484543d1Sopenharmony_ci}
133484543d1Sopenharmony_ci
134484543d1Sopenharmony_ciHWTEST_F(IntervalTest, interval_exception_test, TestSize.Level1)
135484543d1Sopenharmony_ci{
136484543d1Sopenharmony_ci    // case interval begin while last interval not end
137484543d1Sopenharmony_ci    DefaultInterval interval = DefaultInterval(100, QoS(static_cast<int>(qos_deadline_request)));
138484543d1Sopenharmony_ci    int ret = interval.Begin();
139484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
140484543d1Sopenharmony_ci    ret = interval.Begin();
141484543d1Sopenharmony_ci    EXPECT_EQ(ret, -1);
142484543d1Sopenharmony_ci    interval.End();
143484543d1Sopenharmony_ci    ret = interval.Begin();
144484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
145484543d1Sopenharmony_ci    interval.End();
146484543d1Sopenharmony_ci}
147484543d1Sopenharmony_ci
148484543d1Sopenharmony_ciHWTEST_F(IntervalTest, interval_exception2_test, TestSize.Level1)
149484543d1Sopenharmony_ci{
150484543d1Sopenharmony_ci    // case interval function called before begin
151484543d1Sopenharmony_ci    DefaultInterval interval = DefaultInterval(100, QoS(static_cast<int>(qos_deadline_request)));
152484543d1Sopenharmony_ci
153484543d1Sopenharmony_ci    interval.Update(50);
154484543d1Sopenharmony_ci    interval.CheckPoint();
155484543d1Sopenharmony_ci    interval.End();
156484543d1Sopenharmony_ci
157484543d1Sopenharmony_ci    int ret = interval.Begin();
158484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
159484543d1Sopenharmony_ci    interval.End();
160484543d1Sopenharmony_ci}
161484543d1Sopenharmony_ci
162484543d1Sopenharmony_ciHWTEST_F(IntervalTest, fInterval_basic_test, TestSize.Level1)
163484543d1Sopenharmony_ci{
164484543d1Sopenharmony_ci    FrameInterval interval = FrameInterval(100, QoS(static_cast<int>(qos_user_interactive)));
165484543d1Sopenharmony_ci    int ret = interval.Begin();
166484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
167484543d1Sopenharmony_ci    interval.End();
168484543d1Sopenharmony_ci
169484543d1Sopenharmony_ci    ret = interval.Begin();
170484543d1Sopenharmony_ci    interval.Update(50);
171484543d1Sopenharmony_ci
172484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
173484543d1Sopenharmony_ci    usleep(10);
174484543d1Sopenharmony_ci    interval.CheckPoint();
175484543d1Sopenharmony_ci    interval.End();
176484543d1Sopenharmony_ci}
177484543d1Sopenharmony_ci
178484543d1Sopenharmony_ciHWTEST_F(IntervalTest, fInterval_join_test, TestSize.Level1)
179484543d1Sopenharmony_ci{
180484543d1Sopenharmony_ci    FrameInterval interval = FrameInterval(100, QoS(static_cast<int>(qos_user_interactive)));
181484543d1Sopenharmony_ci    int ret = interval.Begin();
182484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
183484543d1Sopenharmony_ci
184484543d1Sopenharmony_ci    interval.Join();
185484543d1Sopenharmony_ci    interval.Leave();
186484543d1Sopenharmony_ci
187484543d1Sopenharmony_ci    interval.End();
188484543d1Sopenharmony_ci}
189484543d1Sopenharmony_ci
190484543d1Sopenharmony_ciHWTEST_F(IntervalTest, fInterval_exception_test, TestSize.Level1)
191484543d1Sopenharmony_ci{
192484543d1Sopenharmony_ci    // case interval begin while last interval not end
193484543d1Sopenharmony_ci    FrameInterval interval = FrameInterval(100, QoS(static_cast<int>(qos_user_interactive)));
194484543d1Sopenharmony_ci    int ret = interval.Begin();
195484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
196484543d1Sopenharmony_ci    ret = interval.Begin();
197484543d1Sopenharmony_ci    EXPECT_EQ(ret, -1);
198484543d1Sopenharmony_ci    interval.End();
199484543d1Sopenharmony_ci    ret = interval.Begin();
200484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
201484543d1Sopenharmony_ci    interval.End();
202484543d1Sopenharmony_ci}
203484543d1Sopenharmony_ci
204484543d1Sopenharmony_ciHWTEST_F(IntervalTest, fInterval_exception2_test, TestSize.Level1)
205484543d1Sopenharmony_ci{
206484543d1Sopenharmony_ci    // case interval function called before begin
207484543d1Sopenharmony_ci    FrameInterval interval = FrameInterval(100, QoS(static_cast<int>(qos_user_interactive)));
208484543d1Sopenharmony_ci
209484543d1Sopenharmony_ci    interval.Update(50);
210484543d1Sopenharmony_ci    interval.CheckPoint();
211484543d1Sopenharmony_ci    interval.End();
212484543d1Sopenharmony_ci
213484543d1Sopenharmony_ci    int ret = interval.Begin();
214484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
215484543d1Sopenharmony_ci    interval.End();
216484543d1Sopenharmony_ci}
217484543d1Sopenharmony_ci
218484543d1Sopenharmony_ciHWTEST_F(IntervalTest, perfctrl_overload_test, TestSize.Level1)
219484543d1Sopenharmony_ci{
220484543d1Sopenharmony_ci    PerfCtrl ctrl = PerfCtrl(QoS(static_cast<int>(qos_deadline_request)));
221484543d1Sopenharmony_ci    ctrl.Begin();
222484543d1Sopenharmony_ci    ctrl.Update(100, UINT_MAX, false);
223484543d1Sopenharmony_ci    ctrl.End();
224484543d1Sopenharmony_ci}
225484543d1Sopenharmony_ci
226484543d1Sopenharmony_ciHWTEST_F(IntervalTest, perfctrl_invalid_qos_test, TestSize.Level1)
227484543d1Sopenharmony_ci{
228484543d1Sopenharmony_ci    PerfCtrl ctrl = PerfCtrl(QoS(static_cast<int>(qos_inherit)));
229484543d1Sopenharmony_ci    ctrl.Begin();
230484543d1Sopenharmony_ci    ctrl.Update(100, 500, false);
231484543d1Sopenharmony_ci    ctrl.End();
232484543d1Sopenharmony_ci}
233484543d1Sopenharmony_ci
234484543d1Sopenharmony_ciHWTEST_F(IntervalTest, loadPredict_basic_test, TestSize.Level1)
235484543d1Sopenharmony_ci{
236484543d1Sopenharmony_ci    IntervalLoadPredictor lp;
237484543d1Sopenharmony_ci
238484543d1Sopenharmony_ci    lp.UpdateTotalLoad(100);
239484543d1Sopenharmony_ci    lp.UpdateTotalLoad(200);
240484543d1Sopenharmony_ci    lp.UpdateTotalLoad(300);
241484543d1Sopenharmony_ci
242484543d1Sopenharmony_ci    uint64_t load = lp.GetTotalLoad();
243484543d1Sopenharmony_ci    // max among average and recent 2 load
244484543d1Sopenharmony_ci    EXPECT_EQ(load, 300);
245484543d1Sopenharmony_ci}