1 /*
2  * Copyright (c) 2023-2024 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 "gtest/hwext/gtest-multithread.h"
18 
19 #include <unordered_map>
20 #include <vector>
21 #include "nativetoken_kit.h"
22 #include "res_sched_client.h"
23 #include "res_type.h"
24 #include "res_sched_systemload_notifier_client.h"
25 #include "res_sched_event_listener.h"
26 #include "token_setproc.h"
27 
28 namespace OHOS {
29 namespace ResourceSchedule {
30 using namespace std;
31 using namespace testing::ext;
32 using namespace testing::mt;
33 static constexpr int32_t RSS_SA_ID = 1901;
34 static constexpr int32_t OTHER_SA_ID = 1900;
35 class ResSchedClientTest : public testing::Test {
36 public:
37     static void SetUpTestCase(void);
38     static void TearDownTestCase(void);
39     void SetUp();
40     void TearDown();
41     void MockProcess(int32_t uid);
42 };
43 
44 
SetUpTestCase(void)45 void ResSchedClientTest::SetUpTestCase(void) {}
46 
TearDownTestCase()47 void ResSchedClientTest::TearDownTestCase() {}
48 
SetUp()49 void ResSchedClientTest::SetUp() {}
50 
TearDown()51 void ResSchedClientTest::TearDown() {}
52 
MockProcess(int32_t uid)53 void ResSchedClientTest::MockProcess(int32_t uid)
54 {
55     static const char *perms[] = {
56         "ohos.permission.DISTRIBUTED_DATASYNC"
57     };
58     uint64_t tokenId;
59     NativeTokenInfoParams infoInstance = {
60         .dcapsNum = 0,
61         .permsNum = 1,
62         .aclsNum = 0,
63         .dcaps = nullptr,
64         .perms = perms,
65         .acls = nullptr,
66         .processName = "samgr",
67         .aplStr = "system_core",
68     };
69     tokenId = GetAccessTokenId(&infoInstance);
70     SetSelfTokenID(tokenId);
71     setuid(uid);
72 }
73 
74 class ResSchedSystemloadNotifierClientMock : public ResSchedSystemloadNotifierClient {
75 public:
76     ResSchedSystemloadNotifierClientMock() = default;
77     ~ResSchedSystemloadNotifierClientMock() = default;
OnSystemloadLevel(int32_t level)78     void OnSystemloadLevel(int32_t level) override
79     {
80         levels = level;
81     }
82     static int32_t levels;
83 };
84 
85 int32_t ResSchedSystemloadNotifierClientMock::levels = 0;
86 
87 class ResSchedEventListenerMock : public ResSchedEventListener {
88 public:
89     ResSchedEventListenerMock() = default;
90     ~ResSchedEventListenerMock() = default;
OnReceiveEvent(uint32_t eventType,uint32_t eventValue,std::unordered_map<std::string,std::string> extInfo)91     void OnReceiveEvent(uint32_t eventType, uint32_t eventValue,
92         std::unordered_map<std::string, std::string> extInfo) override
93     {
94         type = eventType;
95         value = eventValue;
96     }
97     static int32_t type;
98     static int32_t value;
99 };
100 
101 int32_t ResSchedEventListenerMock::type = 0;
102 int32_t ResSchedEventListenerMock::value = 0;
103 
104 /**
105  * @tc.name: KillProcess001
106  * @tc.desc: kill process stable test
107  * @tc.type: FUNC
108  * @tc.require: I6EEJI
109  * @tc.author: qiunaiguang
110  */
111 HWTEST_F(ResSchedClientTest, KillProcess001, Function | MediumTest | Level0)
112 {
113     int32_t uid = 5555;
114     MockProcess(uid);
115     std::unordered_map<std::string, std::string> mapPayload;
116     mapPayload["pid"] = "65535";
117     mapPayload["processName"] = "test";
118     for (int i = 0; i < 100; i++) {
119         ResSchedClient::GetInstance().KillProcess(mapPayload);
120     }
121     EXPECT_TRUE(ResSchedClient::GetInstance().rss_);
122 }
123 
124 /**
125  * @tc.name: KillProcess002
126  * @tc.desc: kill process error test
127  * @tc.type: FUNC
128  * @tc.require: I6EEJI
129  * @tc.author: qiunaiguang
130  */
131 HWTEST_F(ResSchedClientTest, KillProcess002, Function | MediumTest | Level0)
132 {
133     int32_t uid = 5555;
134     MockProcess(uid);
135     std::unordered_map<std::string, std::string> mapPayload;
136     ResSchedClient::GetInstance().KillProcess(mapPayload);
137     EXPECT_TRUE(ResSchedClient::GetInstance().rss_);
138 
139     mapPayload["pid"] = "TEST";
140     ResSchedClient::GetInstance().KillProcess(mapPayload);
141     EXPECT_TRUE(ResSchedClient::GetInstance().rss_);
142 
143     mapPayload["pid"] = "65535";
144     mapPayload["processName"] = "test";
145     ResSchedClient::GetInstance().KillProcess(mapPayload);
146     EXPECT_TRUE(ResSchedClient::GetInstance().rss_);
147 
148     uid = 6666;
149     MockProcess(uid);
150     ResSchedClient::GetInstance().KillProcess(mapPayload);
151     EXPECT_TRUE(ResSchedClient::GetInstance().rss_);
152 }
153 
StartKillProcess()154 static void StartKillProcess()
155 {
156     std::unordered_map<std::string, std::string> payload;
157     payload["pid"] = "65535";
158     payload["processName"] = "test_process";
159     ResSchedClient::GetInstance().KillProcess(payload);
160     EXPECT_TRUE(ResSchedClient::GetInstance().rss_);
161 }
162 
163 /**
164  * @tc.name: MultiThreadKillProcess
165  * @tc.desc: multi-thread invoking test
166  * @tc.type: FUNC
167  * @tc.require: IACR9M
168  */
169 HWTEST_F(ResSchedClientTest, MultiThreadKillProcess, Function | MediumTest | Level0)
170 {
171     SET_THREAD_NUM(10);
172     GTEST_RUN_TASK(StartKillProcess);
173 }
174 
StartReportSyncEvent()175 static void StartReportSyncEvent()
176 {
177     uint32_t resType = ResType::SYNC_RES_TYPE_THAW_ONE_APP;
178     nlohmann::json payload;
179     payload.emplace("pid", 1);
180     payload.emplace("reason", "test_reason");
181     nlohmann::json reply;
182     int32_t ret = ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
183     // 权限校验失败,返回err
184     EXPECT_NE(ret, 0);
185     EXPECT_TRUE(ResSchedClient::GetInstance().rss_);
186 }
187 
188 /**
189  * @tc.name: MultiThreadReportSyncEvent
190  * @tc.desc: multi-thread invoking test
191  * @tc.type: FUNC
192  * @tc.require: IACR9M
193  */
194 HWTEST_F(ResSchedClientTest, MultiThreadReportSyncEvent, Function | MediumTest | Level0)
195 {
196     SET_THREAD_NUM(10);
197     GTEST_RUN_TASK(StartReportSyncEvent);
198 }
199 
200 /**
201  * @tc.name: ReportSyncEvent
202  * @tc.desc: test func ReportSyncEvent
203  * @tc.type: FUNC
204  * @tc.require: I9QN9E
205  */
206 HWTEST_F(ResSchedClientTest, ReportSyncEvent, Function | MediumTest | Level0)
207 {
208     uint32_t resType = ResType::SYNC_RES_TYPE_THAW_ONE_APP;
209     nlohmann::json payload;
210     payload.emplace("pid", 1);
211     payload.emplace("reason", "test_reason");
212     nlohmann::json reply;
213     int32_t ret = ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
214     // 权限校验失败,返回err
215     EXPECT_NE(ret, 0);
216 }
217 
218 /**
219  * @tc.name: RegisterSystemloadNotifier001
220  * @tc.desc: Register systemload notifier
221  * @tc.type: FUNC
222  * @tc.require: issueI9G149
223  * @tc.author: shanhaiyang
224  */
225 HWTEST_F(ResSchedClientTest, RegisterSystemloadNotifier001, Function | MediumTest | Level0)
226 {
227     sptr<ResSchedSystemloadNotifierClient> notifier =
228         new (std::nothrow) ResSchedSystemloadNotifierClientMock;
229     EXPECT_TRUE(notifier != nullptr);
230     ResSchedClient::GetInstance().RegisterSystemloadNotifier(notifier);
231     ResSchedClient::GetInstance().RegisterSystemloadNotifier(notifier);
232     ResSchedClient::GetInstance().systemloadLevelListener_->OnSystemloadLevel(2);
233     EXPECT_TRUE(ResSchedSystemloadNotifierClientMock::levels == 2);
234     ResSchedSystemloadNotifierClientMock::levels = 0;
235     ResSchedClient::GetInstance().UnRegisterSystemloadNotifier(notifier);
236 }
237 
238 /**
239  * @tc.name: UnRegisterSystemloadNotifier001
240  * @tc.desc: UnRegister systemload notifier
241  * @tc.type: FUNC
242  * @tc.require: issueI9G149
243  * @tc.author: shanhaiyang
244  */
245 HWTEST_F(ResSchedClientTest, UnRegisterSystemloadNotifier001, Function | MediumTest | Level0)
246 {
247     sptr<ResSchedSystemloadNotifierClient> notifier =
248         new (std::nothrow) ResSchedSystemloadNotifierClientMock;
249     EXPECT_TRUE(notifier != nullptr);
250     ResSchedClient::GetInstance().RegisterSystemloadNotifier(notifier);
251     ResSchedClient::GetInstance().UnRegisterSystemloadNotifier(notifier);
252     ResSchedClient::GetInstance().systemloadLevelListener_->OnSystemloadLevel(2);
253     EXPECT_TRUE(ResSchedSystemloadNotifierClientMock::levels == 0);
254 }
255 
256 /**
257  * @tc.name: RegisterEventListener001
258  * @tc.desc: Register event listener
259  * @tc.type: FUNC
260  * @tc.require: issueIA9UZ9
261  * @tc.author: baiheng
262  */
263 HWTEST_F(ResSchedClientTest, RegisterEventListener001, Function | MediumTest | Level0)
264 {
265     sptr<ResSchedEventListener> eventListener =
266         new (std::nothrow) ResSchedEventListenerMock;
267     EXPECT_TRUE(eventListener != nullptr);
268     ResSchedClient::GetInstance().RegisterEventListener(eventListener,
269         ResType::EventType::EVENT_DRAW_FRAME_REPORT);
270     ResSchedClient::GetInstance().RegisterEventListener(eventListener,
271         ResType::EventType::EVENT_DRAW_FRAME_REPORT);
272     nlohmann::json extInfo;
273     ResSchedClient::GetInstance().innerEventListener_->OnReceiveEvent(ResType::EventType::EVENT_DRAW_FRAME_REPORT,
274         ResType::EventValue::EVENT_VALUE_DRAW_FRAME_REPORT_START,
275         ResType::EventListenerGroup::LISTENER_GROUP_COMMON, extInfo);
276     EXPECT_TRUE(ResSchedEventListenerMock::type == ResType::EventType::EVENT_DRAW_FRAME_REPORT);
277     EXPECT_TRUE(ResSchedEventListenerMock::value == ResType::EventValue::EVENT_VALUE_DRAW_FRAME_REPORT_START);
278     ResSchedEventListenerMock::type = 0;
279     ResSchedEventListenerMock::value = 0;
280     ResSchedClient::GetInstance().UnRegisterEventListener(eventListener,
281         ResType::EventType::EVENT_DRAW_FRAME_REPORT);
282     SUCCEED();
283 }
284 
285 /**
286  * @tc.name: UnRegisterEventListener001
287  * @tc.desc: UnRegister event listener
288  * @tc.type: FUNC
289  * @tc.require: issueIA9UZ9
290  * @tc.author: baiheng
291  */
292 HWTEST_F(ResSchedClientTest, UnRegisterEventListener001, Function | MediumTest | Level0)
293 {
294     sptr<ResSchedEventListener> eventListener =
295         new (std::nothrow) ResSchedEventListenerMock;
296     EXPECT_TRUE(eventListener != nullptr);
297     ResSchedClient::GetInstance().RegisterEventListener(eventListener,
298         ResType::EventType::EVENT_DRAW_FRAME_REPORT);
299     ResSchedClient::GetInstance().UnRegisterEventListener(eventListener,
300         ResType::EventType::EVENT_DRAW_FRAME_REPORT);
301     nlohmann::json extInfo;
302     ResSchedClient::GetInstance().innerEventListener_->OnReceiveEvent(ResType::EventType::EVENT_DRAW_FRAME_REPORT,
303         ResType::EventValue::EVENT_VALUE_DRAW_FRAME_REPORT_START,
304         ResType::EventListenerGroup::LISTENER_GROUP_COMMON, extInfo);
305     EXPECT_TRUE(ResSchedEventListenerMock::type == 0);
306     EXPECT_TRUE(ResSchedEventListenerMock::value == 0);
307 }
308 
309 /**
310  * @tc.name: GetSystemloadLevel001
311  * @tc.desc: Get systemload level
312  * @tc.type: FUNC
313  * @tc.require: issueI9G149
314  * @tc.author: shanhaiyang
315  */
316 HWTEST_F(ResSchedClientTest, GetSystemloadLevel001, Function | MediumTest | Level0)
317 {
318     int32_t res = ResSchedClient::GetInstance().GetSystemloadLevel();
319     EXPECT_TRUE(ResSchedClient::GetInstance().rss_);
320 }
321 
322 /**
323  * @tc.name: ResSchedSvcStatusChange add 001
324  * @tc.desc: ResSchedSvcStatusChange OnAddSystemAbility
325  * @tc.type: FUNC
326  * @tc.require: issueI9G149
327  * @tc.author: shanhaiyang
328  */
329 HWTEST_F(ResSchedClientTest, OnAddSystemAbility001, Function | MediumTest | Level0)
330 {
331     ASSERT_TRUE(ResSchedClient::GetInstance().resSchedSvcStatusListener_);
332     std::string empty;
333     ResSchedClient::GetInstance().resSchedSvcStatusListener_->OnAddSystemAbility(RSS_SA_ID, empty);
334     sptr<ResSchedSystemloadNotifierClient> notifier =
335         new (std::nothrow) ResSchedSystemloadNotifierClientMock;
336     EXPECT_TRUE(notifier != nullptr);
337     ResSchedClient::GetInstance().RegisterSystemloadNotifier(notifier);
338     ResSchedClient::GetInstance().UnRegisterSystemloadNotifier(notifier);
339     SUCCEED();
340 }
341 
342 /**
343  * @tc.name: ResSchedSvcStatusChange add 002
344  * @tc.desc: ResSchedSvcStatusChange OnAddSystemAbility
345  * @tc.type: FUNC
346  * @tc.require: issueI9G149
347  * @tc.author: shanhaiyang
348  */
349 HWTEST_F(ResSchedClientTest, OnAddSystemAbility002, Function | MediumTest | Level0)
350 {
351     ASSERT_TRUE(ResSchedClient::GetInstance().resSchedSvcStatusListener_);
352     std::string empty;
353     ResSchedClient::GetInstance().resSchedSvcStatusListener_->OnAddSystemAbility(RSS_SA_ID, empty);
354     sptr<ResSchedSystemloadNotifierClient> notifier =
355         new (std::nothrow) ResSchedSystemloadNotifierClientMock;
356     EXPECT_TRUE(notifier != nullptr);
357     ResSchedClient::GetInstance().RegisterSystemloadNotifier(notifier);
358     ResSchedClient::GetInstance().UnRegisterSystemloadNotifier(notifier);
359     SUCCEED();
360 }
361 
362 /**
363  * @tc.name: ResSchedSvcStatusChange remove 001
364  * @tc.desc: ResSchedSvcStatusChange OnRemoveSystemAbility
365  * @tc.type: FUNC
366  * @tc.require: issueI9G149
367  * @tc.author: shanhaiyang
368  */
369 HWTEST_F(ResSchedClientTest, OnRemoveSystemAbility001, Function | MediumTest | Level0)
370 {
371     sptr<ResSchedSystemloadNotifierClient> notifier =
372         new (std::nothrow) ResSchedSystemloadNotifierClientMock;
373     EXPECT_TRUE(notifier != nullptr);
374     ResSchedClient::GetInstance().RegisterSystemloadNotifier(notifier);
375     ASSERT_TRUE(ResSchedClient::GetInstance().resSchedSvcStatusListener_);
376     std::string empty;
377     ResSchedClient::GetInstance().resSchedSvcStatusListener_->OnRemoveSystemAbility(OTHER_SA_ID, empty);
378     ResSchedClient::GetInstance().UnRegisterSystemloadNotifier(notifier);
379     SUCCEED();
380 }
381 
382 /**
383  * @tc.name: IsAllowedAppPreload
384  * @tc.desc: Is allowed application preload
385  * @tc.type: FUNC
386  * @tc.require: issueI9C9JN
387  * @tc.author: xiaoshun
388  */
389 HWTEST_F(ResSchedClientTest, IsAllowedAppPreload, Function | MediumTest | Level0)
390 {
391     std::string bundleName = "com.ohos.test";
392     EXPECT_TRUE(ResSchedClient::GetInstance().rss_);
393     EXPECT_TRUE(!ResSchedClient::GetInstance().IsAllowedAppPreload(bundleName, 0));
394 }
395 
396 /**
397  * @tc.name: StopRemoteObject
398  * @tc.desc: Stop Remote Object
399  * @tc.type: FUNC
400  * @tc.require: I78O6Y
401  * @tc.author: lujunchao
402  */
403 HWTEST_F(ResSchedClientTest, StopRemoteObject, Function | MediumTest | Level0)
404 {
405     ResSchedClient::GetInstance().StopRemoteObject();
406     EXPECT_TRUE(nullptr == ResSchedClient::GetInstance().rss_);
407 }
408 } // namespace ResourceSchedule
409 } // namespace OHOS
410