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 #include <gmock/gmock.h>
18 #define private public
19 #define protected public
20 #include <eu/scpu_monitor.h>
21 #undef private
22 #undef protected
23 
24 #include "qos.h"
25 #include "../common.h"
26 
27 using namespace testing;
28 #ifdef HWTEST_TESTING_EXT_ENABLE
29 using namespace testing::ext;
30 #endif
31 using namespace ffrt;
32 using ::testing::Return;
33 
34 class WorkerManager {
35 public:
IncWorker(const QoS& qos)36     virtual bool IncWorker(const QoS& qos)
37     {
38         return true;
39     }
WakeupWorkers(const QoS& qos)40     virtual void WakeupWorkers(const QoS& qos)
41     {
42     }
GetTaskCount(const QoS& qos)43     virtual int GetTaskCount(const QoS& qos)
44     {
45         return 0;
46     }
GetWorkerCount(const QoS& qos)47     virtual int GetWorkerCount(const QoS& qos)
48     {
49         return 0;
50     }
51 };
52 
53 class MockWorkerManager : public WorkerManager {
54 public:
MockWorkerManager()55     MockWorkerManager()
56     {
57     }
~MockWorkerManager()58     ~MockWorkerManager()
59     {
60     }
61     MOCK_METHOD1(IncWorker, bool(const QoS&));
62     MOCK_METHOD1(WakeupWorkers, void(const QoS&));
63     MOCK_METHOD1(GetTaskCount, int(const QoS&));
64     MOCK_METHOD1(GetWorkerCount, int(const QoS&));
65 };
66 
67 class CpuMonitorTest : public testing::Test {
68 protected:
SetUpTestCase()69     static void SetUpTestCase()
70     {
71     }
72 
TearDownTestCase()73     static void TearDownTestCase()
74     {
75     }
76 
SetUp()77     virtual void SetUp()
78     {
79     }
80 
TearDown()81     virtual void TearDown()
82     {
83     }
84 };
85 
HWTEST_F(CpuMonitorTest, monitor_notify_test, TestSize.Level1)86 HWTEST_F(CpuMonitorTest, monitor_notify_test, TestSize.Level1)
87 {
88     testing::NiceMock<MockWorkerManager> mWmanager;
89     QoS qos(qos_default);
90     SCPUMonitor wmonitor({
91         std::bind(&MockWorkerManager::IncWorker, &mWmanager, std::placeholders::_1),
92         std::bind(&MockWorkerManager::WakeupWorkers, &mWmanager, std::placeholders::_1),
93         std::bind(&MockWorkerManager::GetTaskCount, &mWmanager, std::placeholders::_1),
94         std::bind(&MockWorkerManager::GetWorkerCount, &mWmanager, std::placeholders::_1),
95         CPUMonitor::HandleTaskNotifyDefault});
96 
97     (void)wmonitor.GetMonitorTid();
98 
99     EXPECT_CALL(mWmanager, GetTaskCount(qos)).WillRepeatedly(Return(0));
100 
101     wmonitor.Notify(QoS(static_cast<int>(qos_default)), TaskNotifyType::TASK_ADDED);
102     wmonitor.Notify(QoS(static_cast<int>(qos_default)), TaskNotifyType::TASK_PICKED);
103 
104     EXPECT_EQ(wmonitor.ctrlQueue[qos_default].executionNum, 0);
105     EXPECT_CALL(mWmanager, GetTaskCount(qos)).WillRepeatedly(Return(1));
106     EXPECT_CALL(mWmanager, GetWorkerCount(qos)).WillRepeatedly(Return(5));
107 
108     for (uint32_t idx = 1; idx <= 5; idx++) {
109         wmonitor.Notify(QoS(static_cast<int>(qos_default)), TaskNotifyType::TASK_ADDED);
110         EXPECT_EQ(wmonitor.ctrlQueue[qos_default].executionNum, idx);
111     }
112 
113     wmonitor.Notify(QoS(static_cast<int>(qos_default)), TaskNotifyType::TASK_PICKED);
114     EXPECT_EQ(wmonitor.ctrlQueue[qos_default].executionNum, 5);
115 }
116 
117 // 批量唤醒worker
HWTEST_F(CpuMonitorTest, monitor_notify_workers_test, TestSize.Level1)118 HWTEST_F(CpuMonitorTest, monitor_notify_workers_test, TestSize.Level1)
119 {
120     testing::NiceMock<MockWorkerManager> mWmanager;
121     SCPUMonitor wmonitor({
122         std::bind(&MockWorkerManager::IncWorker, &mWmanager, std::placeholders::_1),
123         std::bind(&MockWorkerManager::WakeupWorkers, &mWmanager, std::placeholders::_1),
124         std::bind(&MockWorkerManager::GetTaskCount, &mWmanager, std::placeholders::_1),
125         std::bind(&MockWorkerManager::GetWorkerCount, &mWmanager, std::placeholders::_1)});
126 
127     QoS qosDefault(qos_default);
128     wmonitor.NotifyWorkers(qosDefault, 3);
129     EXPECT_EQ(wmonitor.ctrlQueue[qos_default].executionNum, 3);
130     wmonitor.NotifyWorkers(qosDefault, 2);
131     EXPECT_EQ(wmonitor.ctrlQueue[qos_default].executionNum, 5);
132     wmonitor.NotifyWorkers(qosDefault, 5);
133     EXPECT_EQ(wmonitor.ctrlQueue[qos_default].executionNum, 8);
134 
135     wmonitor.ctrlQueue[qos_default].executionNum = 4;
136     wmonitor.ctrlQueue[qos_default].sleepingWorkerNum = 4;
137     wmonitor.NotifyWorkers(qosDefault, 5);
138     EXPECT_EQ(wmonitor.ctrlQueue[qos_default].executionNum, 4);
139 }
140 
141 #ifndef FFRT_GITEE
142 /**
143  * @tc.name: TryDestroy
144  * @tc.desc: Test whether the RollbackDestroy interface are normal.
145  * @tc.type: FUNC
146  *
147  *
148  */
HWTEST_F(CpuMonitorTest, monitor_worker_trydestroy_test, TestSize.Level1)149 HWTEST_F(CpuMonitorTest, monitor_worker_trydestroy_test, TestSize.Level1)
150 {
151     testing::NiceMock<MockWorkerManager> mWmanager;
152     SCPUMonitor wmonitor({
153         std::bind(&MockWorkerManager::IncWorker, &mWmanager, std::placeholders::_1),
154         std::bind(&MockWorkerManager::WakeupWorkers, &mWmanager, std::placeholders::_1),
155         std::bind(&MockWorkerManager::GetTaskCount, &mWmanager, std::placeholders::_1),
156         std::bind(&MockWorkerManager::GetWorkerCount, &mWmanager, std::placeholders::_1) });
157 
158     QoS qosDefault(qos_default);
159     wmonitor.ctrlQueue[qos_default].sleepingWorkerNum = 1;
160     wmonitor.TryDestroy(qosDefault);
161     EXPECT_EQ(wmonitor.ctrlQueue[qos_default].sleepingWorkerNum, 0);
162 }
163 
164 /**
165  * @tc.name: RollbackDestroy
166  * @tc.desc: Test whether the RollbackDestroy interface are normal.
167  * @tc.type: FUNC
168  *
169  *
170  */
HWTEST_F(CpuMonitorTest, monitor_worker_rollbackdestroy_test, TestSize.Level1)171 HWTEST_F(CpuMonitorTest, monitor_worker_rollbackdestroy_test, TestSize.Level1)
172 {
173     testing::NiceMock<MockWorkerManager> mWmanager;
174     SCPUMonitor wmonitor({
175         std::bind(&MockWorkerManager::IncWorker, &mWmanager, std::placeholders::_1),
176         std::bind(&MockWorkerManager::WakeupWorkers, &mWmanager, std::placeholders::_1),
177         std::bind(&MockWorkerManager::GetTaskCount, &mWmanager, std::placeholders::_1),
178         std::bind(&MockWorkerManager::GetWorkerCount, &mWmanager, std::placeholders::_1) });
179 
180     QoS qosDefault(qos_default);
181     wmonitor.ctrlQueue[qos_default].executionNum = 0;
182     wmonitor.RollbackDestroy(qosDefault, true);
183     EXPECT_EQ(wmonitor.ctrlQueue[qos_default].executionNum, 1);
184 }
185 #endif
186