1 /*
2  * Copyright (c) 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 <vector>
20 
21 #include "accesstoken_kit.h"
22 #include "ipc_skeleton.h"
23 #include "nativetoken_kit.h"
24 #include "token_setproc.h"
25 
26 #include "plugin_mgr.h"
27 #include "res_exe_type.h"
28 #include "res_sched_exe_common_utils.h"
29 #include "res_sched_exe_constants.h"
30 #include "res_sched_exe_service.h"
31 #include "res_sched_exe_service_ability.h"
32 
33 namespace OHOS {
34 namespace ResourceSchedule {
35 using namespace std;
36 using namespace testing::ext;
37 using namespace testing::mt;
38 using namespace Security::AccessToken;
39 
40 namespace {
41     constexpr int32_t SYNC_THREAD_NUM = 100;
42     constexpr int32_t SYNC_INTERNAL_TIME = 10000;
43 }
44 
45 class ResSchedExeServiceTest : public testing::Test {
46 public:
47     static void SetUpTestCase(void);
48     static void TearDownTestCase(void);
49     void SetUp();
50     void TearDown();
51 protected:
52     std::shared_ptr<ResSchedExeService> resSchedExeService_ = nullptr;
53     std::shared_ptr<ResSchedExeServiceAbility> resSchedExeServiceAbility_ = nullptr;
54 };
55 
SetUpTestCase(void)56 void ResSchedExeServiceTest::SetUpTestCase(void)
57 {
58     static const char *perms[] = {
59         "ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT",
60         "ohos.permission.DUMP",
61     };
62     uint64_t tokenId;
63     NativeTokenInfoParams infoInstance = {
64         .dcapsNum = 0,
65         .permsNum = 2,
66         .aclsNum = 0,
67         .dcaps = nullptr,
68         .perms = perms,
69         .acls = nullptr,
70         .processName = "ResSchedExeServiceTest",
71         .aplStr = "system_core",
72     };
73     tokenId = GetAccessTokenId(&infoInstance);
74     SetSelfTokenID(tokenId);
75     AccessTokenKit::ReloadNativeTokenInfo();
76 }
77 
TearDownTestCase()78 void ResSchedExeServiceTest::TearDownTestCase() {}
79 
SetUp()80 void ResSchedExeServiceTest::SetUp()
81 {
82     /**
83      * @tc.setup: initialize the member variable resSchedExeServiceAbility_
84      */
85     resSchedExeService_ = make_shared<ResSchedExeService>();
86     resSchedExeServiceAbility_ = make_shared<ResSchedExeServiceAbility>();
87 }
88 
TearDown()89 void ResSchedExeServiceTest::TearDown()
90 {
91     /**
92      * @tc.teardown: clear resSchedExeServiceAbility_
93      */
94     resSchedExeService_ = nullptr;
95     resSchedExeServiceAbility_ = nullptr;
96 }
97 
98 /**
99  * @tc.name: resschedexe service dump 001
100  * @tc.desc: Verify if resschedexe service dump commonds is success.
101  * @tc.type: FUNC
102  */
103 HWTEST_F(ResSchedExeServiceTest, ServiceDump001, Function | MediumTest | Level0)
104 {
105     PluginMgr::GetInstance().Init(true);
106     std::string result;
107     resSchedExeService_->DumpAllInfo(result);
108     EXPECT_TRUE(!result.empty());
109 
110     result = "";
111     resSchedExeService_->DumpUsage(result);
112     EXPECT_TRUE(!result.empty());
113 
114     int32_t wrongFd = -1;
115     std::vector<std::u16string> argsNull;
116     int res = resSchedExeService_->Dump(wrongFd, argsNull);
117     EXPECT_NE(res, ResErrCode::RSSEXE_NO_ERR);
118 
119     int32_t correctFd = 0;
120     res = resSchedExeService_->Dump(correctFd, argsNull);
121 
122     std::vector<std::u16string> argsHelp = {to_utf16("-h")};
123     res = resSchedExeService_->Dump(correctFd, argsHelp);
124 
125     std::vector<std::u16string> argsAll = {to_utf16("-a")};
126     res = resSchedExeService_->Dump(correctFd, argsAll);
127 
128     std::vector<std::u16string> argsError = {to_utf16("-e")};
129     res = resSchedExeService_->Dump(correctFd, argsError);
130 
131     std::vector<std::u16string> argsPlugin = {to_utf16("-p")};
132     res = resSchedExeService_->Dump(correctFd, argsPlugin);
133 
134     std::vector<std::u16string> argsOnePlugin = {to_utf16("-p"), to_utf16("1")};
135     res = resSchedExeService_->Dump(correctFd, argsOnePlugin);
136 }
137 
138 /**
139  * @tc.name: Ressched_executor service SendRequestSync001
140  * @tc.desc: Verify if Ressched_executor service SendRequestSync is success.
141  * @tc.type: FUNC
142  */
143 HWTEST_F(ResSchedExeServiceTest, SendRequestSync001, Function | MediumTest | Level0)
144 {
145     nlohmann::json payload;
146     nlohmann::json reply;
147     EXPECT_TRUE(resSchedExeService_ != nullptr);
148     resSchedExeService_->SendRequestSync(0, 0, payload, reply);
149 }
150 
SendRequestSyncTask()151 static void SendRequestSyncTask()
152 {
153     std::shared_ptr<ResSchedExeService> resSchedExeService_ = make_shared<ResSchedExeService>();
154     nlohmann::json payload;
155     nlohmann::json reply;
156     EXPECT_TRUE(resSchedExeService_ != nullptr);
157     for (int i = 0; i < SYNC_THREAD_NUM; i++) {
158         resSchedExeService_->SendRequestSync(0, 0, payload, reply);
159         usleep(SYNC_INTERNAL_TIME);
160     }
161 }
162 
163 /**
164  * @tc.name: Ressched_executor service SendRequestSync002
165  * @tc.desc: Test Ressched_executor service SendRequestSync in multithreading.
166  * @tc.type: FUNC
167  */
168 HWTEST_F(ResSchedExeServiceTest, SendRequestSync002, Function | MediumTest | Level0)
169 {
170     SET_THREAD_NUM(10);
171     GTEST_RUN_TASK(SendRequestSyncTask);
172 }
173 
174 /**
175  * @tc.name: Ressched_executor service SendRequestAsync001
176  * @tc.desc: Verify if Ressched_executor service SendRequestAsync is success.
177  * @tc.type: FUNC
178  */
179 HWTEST_F(ResSchedExeServiceTest, SendRequestAsync001, Function | MediumTest | Level0)
180 {
181     nlohmann::json payload;
182     EXPECT_TRUE(resSchedExeService_ != nullptr);
183     resSchedExeService_->SendRequestAsync(0, 0, payload);
184 }
185 
SendRequestAsyncTask()186 static void SendRequestAsyncTask()
187 {
188     std::shared_ptr<ResSchedExeService> resSchedExeService_ = make_shared<ResSchedExeService>();
189     nlohmann::json payload;
190     for (int i = 0; i < SYNC_THREAD_NUM; i++) {
191         EXPECT_TRUE(resSchedExeService_ != nullptr);
192         resSchedExeService_->SendRequestAsync(0, 0, payload);
193         usleep(SYNC_INTERNAL_TIME);
194     }
195 }
196 
197 /**
198  * @tc.name: Ressched_executor service SendRequestAsync002
199  * @tc.desc: Test Ressched_executor service SendRequestAsync in multithreading.
200  * @tc.type: FUNC
201  */
202 HWTEST_F(ResSchedExeServiceTest, SendRequestAsync002, Function | MediumTest | Level0)
203 {
204     SET_THREAD_NUM(10);
205     GTEST_RUN_TASK(SendRequestAsyncTask);
206 }
207 
208 /**
209  * @tc.name: Start ResSchedExeServiceAbility OnStart001
210  * @tc.desc: Verify if ResSchedExeServiceAbility OnStart is success.
211  * @tc.type: FUNC
212  */
213 HWTEST_F(ResSchedExeServiceTest, OnStart001, Function | MediumTest | Level0)
214 {
215     resSchedExeServiceAbility_->OnStart();
216     EXPECT_TRUE(resSchedExeServiceAbility_->service_ != nullptr);
217 }
218 
OnStartTask()219 static void OnStartTask()
220 {
221     std::shared_ptr<ResSchedExeServiceAbility> resSchedExeServiceAbility_ = make_shared<ResSchedExeServiceAbility>();
222     for (int i = 0; i < SYNC_THREAD_NUM; i++) {
223         resSchedExeServiceAbility_->OnStart();
224         EXPECT_TRUE(resSchedExeServiceAbility_->service_ != nullptr);
225         usleep(SYNC_INTERNAL_TIME);
226     }
227 }
228 
229 /**
230  * @tc.name: Start ResSchedExeServiceAbility OnStart002
231  * @tc.desc: Test ResSchedExeServiceAbility OnStart in multithreading.
232  * @tc.type: FUNC
233  */
234 HWTEST_F(ResSchedExeServiceTest, OnStart002, Function | MediumTest | Level0)
235 {
236     SET_THREAD_NUM(10);
237     GTEST_RUN_TASK(OnStartTask);
238 }
239 
240 /**
241  * @tc.name: Stop ResSchedExeServiceAbility OnStop001
242  * @tc.desc: test the interface Onstop
243  * @tc.type: FUNC
244  */
245 HWTEST_F(ResSchedExeServiceTest, OnStop001, Function | MediumTest | Level0)
246 {
247     resSchedExeServiceAbility_->OnStop();
248     EXPECT_TRUE(resSchedExeServiceAbility_->service_ == nullptr);
249 }
250 
251 class TestResSchedExeServiceStub : public ResSchedExeServiceStub {
252 public:
TestResSchedExeServiceStub()253     TestResSchedExeServiceStub() : ResSchedExeServiceStub() {}
254 
SendRequestAsync(uint32_t restype,int64_t value,const nlohmann::json & context)255     void SendRequestAsync(uint32_t restype, int64_t value, const nlohmann::json& context) override
256     {
257     }
258 
SendRequestSync(uint32_t restype,int64_t value,const nlohmann::json & context,nlohmann::json & reply)259     int32_t SendRequestSync(uint32_t restype, int64_t value,
260         const nlohmann::json& context, nlohmann::json& reply) override
261     {
262         return 0;
263     }
264 
KillProcess(pid_t pid)265     int32_t KillProcess(pid_t pid) override
266     {
267         return 0;
268     }
269 };
270 
271 /**
272  * @tc.name: ResSchedExeServicesStub ReportRequestInner001
273  * @tc.desc: Verify if resschedexestub ReportRequestInner is success.
274  * @tc.type: FUNC
275  */
276 HWTEST_F(ResSchedExeServiceTest, ReportRequestInner001, Function | MediumTest | Level0)
277 {
278     auto resSchedExeServiceStub_ = make_shared<TestResSchedExeServiceStub>();
279     resSchedExeServiceStub_->Init();
280     MessageParcel reply;
281     MessageParcel emptyData;
282     EXPECT_TRUE(resSchedExeServiceStub_->ReportRequestInner(emptyData, reply));
283 
284     MessageParcel reportData;
285     reportData.WriteUint32(1);
286     reportData.WriteInt64(1);
287     reportData.WriteString("{ { \" uid \" : \" 1 \" } }");
288     EXPECT_TRUE(!resSchedExeServiceStub_->ReportRequestInner(reportData, reply));
289 }
290 
ReportRequestInnerTask()291 static void ReportRequestInnerTask()
292 {
293     auto resSchedExeServiceStub_ = make_shared<TestResSchedExeServiceStub>();
294     resSchedExeServiceStub_->Init();
295     MessageParcel reply;
296     for (int i = 0; i < SYNC_THREAD_NUM; i++) {
297         MessageParcel emptyData;
298         EXPECT_TRUE(resSchedExeServiceStub_->ReportRequestInner(emptyData, reply));
299 
300         MessageParcel reportData;
301         reportData.WriteUint32(1);
302         reportData.WriteInt64(1);
303         reportData.WriteString("{ { \" uid \" : \" 1 \" } }");
304         EXPECT_TRUE(!resSchedExeServiceStub_->ReportRequestInner(reportData, reply));
305         usleep(SYNC_INTERNAL_TIME);
306     }
307 }
308 
309 /**
310  * @tc.name: ResSchedExeServicesStub ReportRequestInner002
311  * @tc.desc: Test resschedexestub ReportRequestInner in multithreading.
312  * @tc.type: FUNC
313  */
314 HWTEST_F(ResSchedExeServiceTest, ReportRequestInner002, Function | MediumTest | Level0)
315 {
316     SET_THREAD_NUM(10);
317     GTEST_RUN_TASK(ReportRequestInnerTask);
318 }
319 
320 /**
321  * @tc.name: ResSchedExeServicesStub ReportDebugInner001
322  * @tc.desc: Verify if resschedexestub ReportDebugInner is success.
323  * @tc.type: FUNC
324  */
325 HWTEST_F(ResSchedExeServiceTest, ReportDebugInner001, Function | MediumTest | Level0)
326 {
327     auto resSchedExeServiceStub_ = make_shared<TestResSchedExeServiceStub>();
328     resSchedExeServiceStub_->Init();
329     MessageParcel emptyData;
330     EXPECT_TRUE(resSchedExeServiceStub_->ReportDebugInner(emptyData));
331 
332     MessageParcel reportData;
333     reportData.WriteUint32(ResExeType::RES_TYPE_DEBUG);
334     reportData.WriteUint64(ResSchedExeCommonUtils::GetCurrentTimestampUs());
335     EXPECT_TRUE(!resSchedExeServiceStub_->ReportDebugInner(reportData));
336 }
337 
ReportDebugInnerTask()338 static void ReportDebugInnerTask()
339 {
340     auto resSchedExeServiceStub_ = make_shared<TestResSchedExeServiceStub>();
341     resSchedExeServiceStub_->Init();
342     for (int i = 0; i < SYNC_THREAD_NUM; i++) {
343         MessageParcel emptyData;
344         EXPECT_TRUE(resSchedExeServiceStub_->ReportDebugInner(emptyData));
345 
346         MessageParcel reportData;
347         reportData.WriteUint32(ResExeType::RES_TYPE_DEBUG);
348         reportData.WriteUint64(ResSchedExeCommonUtils::GetCurrentTimestampUs());
349         EXPECT_TRUE(!resSchedExeServiceStub_->ReportDebugInner(reportData));
350         usleep(SYNC_INTERNAL_TIME);
351     }
352 }
353 
354 /**
355  * @tc.name: ResSchedExeServicesStub ReportDebugInner002
356  * @tc.desc: Test resschedexestub ReportDebugInner in multithreading.
357  * @tc.type: FUNC
358  */
359 HWTEST_F(ResSchedExeServiceTest, ReportDebugInner002, Function | MediumTest | Level0)
360 {
361     SET_THREAD_NUM(10);
362     GTEST_RUN_TASK(ReportDebugInnerTask);
363 }
364 
365 /**
366  * @tc.name: ResSchedExeServicesStub RemoteRequest001
367  * @tc.desc: Verify if resschedexestub RemoteRequest is success.
368  * @tc.type: FUNC
369  */
370 HWTEST_F(ResSchedExeServiceTest, RemoteRequest001, Function | MediumTest | Level0)
371 {
372     auto resSchedExeServiceStub_ = make_shared<TestResSchedExeServiceStub>();
373     MessageOption option;
374     MessageParcel reply;
375     int32_t res = resSchedExeServiceStub_->OnRemoteRequest(ResIpcType::REQUEST_SEND_SYNC, reply, reply, option);
376     EXPECT_TRUE(res);
377     res = resSchedExeServiceStub_->OnRemoteRequest(ResIpcType::REQUEST_SEND_ASYNC, reply, reply, option);
378     EXPECT_TRUE(res);
379     res = resSchedExeServiceStub_->OnRemoteRequest(ResIpcType::REQUEST_SEND_DEBUG, reply, reply, option);
380     EXPECT_TRUE(res);
381 }
382 
RemoteRequestTask()383 static void RemoteRequestTask()
384 {
385     auto resSchedExeServiceStub_ = make_shared<TestResSchedExeServiceStub>();
386     MessageOption option;
387     MessageParcel reply;
388     for (int i = 0; i < SYNC_THREAD_NUM; i++) {
389         int32_t res = resSchedExeServiceStub_->OnRemoteRequest(ResIpcType::REQUEST_SEND_SYNC, reply, reply, option);
390         EXPECT_TRUE(res);
391         res = resSchedExeServiceStub_->OnRemoteRequest(ResIpcType::REQUEST_SEND_ASYNC, reply, reply, option);
392         EXPECT_TRUE(res);
393         res = resSchedExeServiceStub_->OnRemoteRequest(ResIpcType::REQUEST_SEND_DEBUG, reply, reply, option);
394         EXPECT_TRUE(res);
395         usleep(SYNC_INTERNAL_TIME);
396     }
397 }
398 
399 /**
400  * @tc.name: ResSchedExeServicesStub RemoteRequest002
401  * @tc.desc: Test resschedexestub RemoteRequest in multithreading.
402  * @tc.type: FUNC
403  */
404 HWTEST_F(ResSchedExeServiceTest, RemoteRequest002, Function | MediumTest | Level0)
405 {
406     SET_THREAD_NUM(10);
407     GTEST_RUN_TASK(RemoteRequestTask);
408 }
409 
410 /**
411  * @tc.name: ResSchedExeServicesStub ParseParcel001
412  * @tc.desc: Verify if resschedexestub ParseParcel is success.
413  * @tc.type: FUNC
414  */
415 HWTEST_F(ResSchedExeServiceTest, ParseParcel001, Function | MediumTest | Level0)
416 {
417     auto resSchedExeServiceStub_ = make_shared<TestResSchedExeServiceStub>();
418     resSchedExeServiceStub_->Init();
419     uint32_t resType = 0;
420     int64_t value = 0;
421     nlohmann::json context;
422     MessageParcel emptyData;
423     EXPECT_FALSE(resSchedExeServiceStub_->ParseParcel(emptyData, resType, value, context));
424 
425     MessageParcel reportData;
426     reportData.WriteUint32(1);
427     reportData.WriteInt64(1);
428     reportData.WriteString("{ { \" uid \" : \" 1 \" } }");
429     EXPECT_TRUE(resSchedExeServiceStub_->ParseParcel(reportData, resType, value, context));
430 }
431 
ParseParcelTask()432 static void ParseParcelTask()
433 {
434     auto resSchedExeServiceStub_ = make_shared<TestResSchedExeServiceStub>();
435     resSchedExeServiceStub_->Init();
436     uint32_t resType = 0;
437     int64_t value = 0;
438     nlohmann::json context;
439     for (int i = 0; i < SYNC_THREAD_NUM; i++) {
440         MessageParcel emptyData;
441         EXPECT_FALSE(resSchedExeServiceStub_->ParseParcel(emptyData, resType, value, context));
442 
443         MessageParcel reportData;
444         reportData.WriteUint32(1);
445         reportData.WriteInt64(1);
446         reportData.WriteString("{ { \" uid \" : \" 1 \" } }");
447         EXPECT_TRUE(resSchedExeServiceStub_->ParseParcel(reportData, resType, value, context));
448         usleep(SYNC_INTERNAL_TIME);
449     }
450 }
451 
452 /**
453  * @tc.name: ResSchedExeServicesStub ParseParcel002
454  * @tc.desc: Test resschedexestub ParseParcel in multithreading.
455  * @tc.type: FUNC
456  */
457 HWTEST_F(ResSchedExeServiceTest, ParseParcel002, Function | MediumTest | Level0)
458 {
459     SET_THREAD_NUM(10);
460     GTEST_RUN_TASK(ParseParcelTask);
461 }
462 } // namespace ResourceSchedule
463 } // namespace OHOS
464