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 #define private public
19 #define protected public
20 #include <fcntl.h>
21 #include <securec.h>
22 #include <sys/ioctl.h>
23 #include <unistd.h>
24 #include "rtg_interface.h"
25 #undef private
26 #undef protected
27
28 namespace OHOS {
29 namespace RME {
30 using namespace testing;
31 using namespace testing::ext;
32
33 #define RTG_INTERFACE_SO_PATH "/system/lib/librtg_interface.z.so"
34
35 enum rtg_type : int {
36 VIP = 0,
37 TOP_TASK_KEY,
38 NORMAL_TASK,
39 RTG_TYPE_MAX,
40 };
41
42 class RtgInterfaceTest : public testing::Test {
43 public:
44 static void SetUpTestCase();
45 static void TearDownTestCase();
46 void SetUp();
47 void TearDown();
48 };
49
50 namespace {
51 const char RTG_SCHED_IPC_MAGIC = 0xAB;
52 }
53
54 #define CMD_ID_SET_RTG \
55 _IOWR(RTG_SCHED_IPC_MAGIC, SET_RTG, struct rtg_str_data)
56
CreateNewRtgGrp(int prioType,int rtNum)57 int CreateNewRtgGrp(int prioType, int rtNum)
58 {
59 struct rtg_grp_data grp_data;
60 int ret;
61 char fileName[] = "/proc/self/sched_rtg_ctrl";
62 int fd = open(fileName, O_RDWR);
63 if (fd < 0) {
64 return fd;
65 }
66 (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
67 if ((prioType > 0) && (prioType < RTG_TYPE_MAX)) {
68 grp_data.prio_type = prioType;
69 }
70 if (rtNum > 0) {
71 grp_data.rt_cnt = rtNum;
72 }
73 grp_data.rtg_cmd = CMD_CREATE_RTG_GRP;
74 ret = ioctl(fd, CMD_ID_SET_RTG, &grp_data);
75 close(fd);
76 return ret;
77 }
78
SetUpTestCase()79 void RtgInterfaceTest::SetUpTestCase()
80 {
81 }
82
TearDownTestCase()83 void RtgInterfaceTest::TearDownTestCase()
84 {
85 }
86
SetUp()87 void RtgInterfaceTest::SetUp()
88 {
89 // must enable rtg before use the interface
90 bool ret = EnableRtg(true);
91 EXPECT_EQ(ret, false);
92 }
93
TearDown()94 void RtgInterfaceTest::TearDown()
95 {
96 // disable rtg after use the interface
97 bool ret = EnableRtg(false);
98 EXPECT_EQ(ret, false);
99 }
100
101 /**
102 * @tc.name: RtgInterfaceCreateAndDestroy
103 * @tc.desc: Verify the CreateAndDestroy function.
104 * @tc.type: FUNC
105 */
106 HWTEST_F(RtgInterfaceTest, RtgInterfaceCreateAndDestroy, TestSize.Level1)
107 {
108 int ret;
109 int grpId;
110 grpId = CreateNewRtgGrp(NORMAL_TASK, 0);
111 EXPECT_GT(grpId, 0);
112 ret = DestroyRtgGrp(grpId);
113 EXPECT_EQ(ret, 0);
114 }
115
116 /**
117 * @tc.name: RtgInterfaceDestroyErrorGroup
118 * @tc.desc: Verify Destroy function with error param.
119 * @tc.type: FUNC
120 */
121 HWTEST_F(RtgInterfaceTest, RtgInterfaceDestroyErrorGroup, TestSize.Level1)
122 {
123 int ret;
124 ret = DestroyRtgGrp(-1);
125 EXPECT_NE(ret, 0);
126 }
127
128 /**
129 * @tc.name: RtgInterfaceAddRtg
130 * @tc.desc: Verify Rtg add function.
131 * @tc.type: FUNC
132 */
133 HWTEST_F(RtgInterfaceTest, RtgInterfaceAddRtg, TestSize.Level1)
134 {
135 int ret;
136 int grpId;
137 int pid = getpid();
138 grpId = CreateNewRtgGrp(VIP, 0);
139 EXPECT_GT(grpId, 0);
140 ret = AddThreadToRtg(pid, grpId);
141 EXPECT_EQ(ret, 0);
142 ret = DestroyRtgGrp(grpId);
143 EXPECT_EQ(ret, 0);
144 }
145
146 /**
147 * @tc.name: RtgInterfaceAddErrorThread
148 * @tc.desc: Verify Rtg add function with error pid.
149 * @tc.type: FUNC
150 */
151 HWTEST_F(RtgInterfaceTest, RtgInterfaceAddErrorThread, TestSize.Level1)
152 {
153 int ret;
154 int grpId;
155 grpId = CreateNewRtgGrp(VIP, 0);
156 EXPECT_GT(grpId, 0);
157 ret = AddThreadToRtg(-1, grpId);
158 EXPECT_NE(ret, 0);
159 ret = DestroyRtgGrp(grpId);
160 EXPECT_EQ(ret, 0);
161 }
162
163 /**
164 * @tc.name: RtgInterfaceAddErrorGroup
165 * @tc.desc: Verify Rtg add function with error groupid.
166 * @tc.type: FUNC
167 */
168 HWTEST_F(RtgInterfaceTest, RtgInterfaceAddErrorGroup, TestSize.Level1)
169 {
170 int ret;
171 int grpId;
172 int pid = getpid();
173 grpId = CreateNewRtgGrp(VIP, 0);
174 EXPECT_GT(grpId, 0);
175 ret = AddThreadToRtg(pid, (grpId + 1));
176 EXPECT_NE(ret, 0);
177 ret = AddThreadToRtg(pid, -1);
178 EXPECT_NE(ret, 0);
179 ret = DestroyRtgGrp(grpId);
180 EXPECT_EQ(ret, 0);
181 }
182
183 /**
184 * @tc.name: RtgInterfaceAddRtgs
185 * @tc.desc: Verify Rtg add multiple thread function.
186 * @tc.type: FUNC
187 */
188 HWTEST_F(RtgInterfaceTest, RtgInterfaceAddRtgs, TestSize.Level1)
189 {
190 int ret;
191 int grpId;
192 int pid = getpid();
193 vector<int> pids = {};
194 pids.push_back(pid);
195 grpId = CreateNewRtgGrp(VIP, 0);
196 EXPECT_GT(grpId, 0);
197 ret = AddThreadsToRtg(pids, grpId);
198 EXPECT_EQ(ret, 0);
199 ret = DestroyRtgGrp(grpId);
200 EXPECT_EQ(ret, 0);
201 }
202
203
204 /**
205 * @tc.name: RtgInterfaceBeginFrameFreq
206 * @tc.desc: Verify rtg frame start function.
207 * @tc.type: FUNC
208 */
209 HWTEST_F(RtgInterfaceTest, RtgInterfaceBeginFrameFreq, TestSize.Level1)
210 {
211 int ret;
212 int grpId;
213 int pid = getpid();
214 vector<int> pids = {};
215 pids.push_back(pid);
216 grpId = CreateNewRtgGrp(VIP, 0);
217 EXPECT_GT(grpId, 0);
218 ret = AddThreadsToRtg(pids, grpId);
219 EXPECT_EQ(ret, 0);
220 ret = BeginFrameFreq(0);
221 EXPECT_EQ(ret, 0);
222 ret = DestroyRtgGrp(grpId);
223 EXPECT_EQ(ret, 0);
224 }
225
226
227 /**
228 * @tc.name: RtgInterfaceBeginFrameFreqWithNoAddThreadtoGrp
229 * @tc.desc: Verify rtg frame start function with NoAddThreadtoGrp.
230 * @tc.type: FUNC
231 */
232 HWTEST_F(RtgInterfaceTest, RtgInterfaceBeginFrameFreqWithNoAddThreadtoGrp, TestSize.Level1)
233 {
234 int ret;
235 int grpId;
236 grpId = CreateNewRtgGrp(VIP, 0);
237 EXPECT_GT(grpId, 0);
238 ret = BeginFrameFreq(0);
239 EXPECT_NE(ret, 0);
240 ret = DestroyRtgGrp(grpId);
241 EXPECT_EQ(ret, 0);
242 }
243
244
245 /**
246 * @tc.name: RtgInterfaceBeginFrameFreqWithErrorParam
247 * @tc.desc: Verify rtg frame start function with error Parameter.
248 * @tc.type: FUNC
249 */
250 HWTEST_F(RtgInterfaceTest, RtgInterfaceBeginFrameFreqWithErrorParam, TestSize.Level1)
251 {
252 int ret;
253 ret = BeginFrameFreq(-1);
254 EXPECT_NE(ret, 0);
255 }
256
257 /**
258 * @tc.name: RtgInterfaceEndFrameFreq
259 * @tc.desc: Verify rtg frame end function.
260 * @tc.type: FUNC
261 */
262 HWTEST_F(RtgInterfaceTest, RtgInterfaceEndFrameFreq, TestSize.Level1)
263 {
264 int ret;
265 int grpId;
266 int pid = getpid();
267 vector<int> pids = {};
268 pids.push_back(pid);
269 grpId = CreateNewRtgGrp(VIP, 0);
270 EXPECT_GT(grpId, 0);
271 ret = AddThreadsToRtg(pids, grpId);
272 EXPECT_EQ(ret, 0);
273 ret = EndFrameFreq(0);
274 EXPECT_EQ(ret, 0);
275 ret = DestroyRtgGrp(grpId);
276 EXPECT_EQ(ret, 0);
277 }
278
279 /**
280 * @tc.name: RtgInterfaceEndFrameFreqWithNoAddThreadtoGrp
281 * @tc.desc: Verify rtg frame end function with NoAddThreadtoGrp.
282 * @tc.type: FUNC
283 */
284 HWTEST_F(RtgInterfaceTest, RtgInterfaceEndFrameFreqWithNoAddThreadtoGrp, TestSize.Level1)
285 {
286 int ret;
287 int grpId;
288 grpId = CreateNewRtgGrp(VIP, 0);
289 EXPECT_GT(grpId, 0);
290 ret = EndFrameFreq(0);
291 EXPECT_NE(ret, 0);
292 ret = DestroyRtgGrp(grpId);
293 EXPECT_EQ(ret, 0);
294 }
295 /**
296 * @tc.name: RtgInterfaceEndFrameFreqWithErrorParam
297 * @tc.desc: Verify rtg frame end function with error Parameter.
298 * @tc.type: FUNC
299 */
300 HWTEST_F(RtgInterfaceTest, RtgInterfaceEndFrameFreqWithErrorParam, TestSize.Level1)
301 {
302 int ret;
303 ret = EndFrameFreq(-1);
304 EXPECT_NE(ret, 0);
305 }
306
307 /**
308 * @tc.name: RtgInterfaceEndScene
309 * @tc.desc: Verify rtg frame scene end function.
310 * @tc.type: FUNC
311 */
312 HWTEST_F(RtgInterfaceTest, RtgInterfaceEndScene, TestSize.Level1)
313 {
314 int ret;
315 int grpId;
316 int pid = getpid();
317 vector<int> pids = {};
318 pids.push_back(pid);
319 grpId = CreateNewRtgGrp(VIP, 0);
320 EXPECT_GT(grpId, 0);
321 ret = AddThreadsToRtg(pids, grpId);
322 EXPECT_EQ(ret, 0);
323 ret = EndScene(grpId);
324 EXPECT_EQ(ret, 0);
325 ret = DestroyRtgGrp(grpId);
326 EXPECT_EQ(ret, 0);
327 }
328
329 /**
330 * @tc.name: RtgInterfaceEndSceneWithErrorGrp
331 * @tc.desc: Verify rtg frame scene end function with error groupid.
332 * @tc.type: FUNC
333 */
334 HWTEST_F(RtgInterfaceTest, RtgInterfaceEndSceneWithErrorGrp, TestSize.Level1)
335 {
336 int ret;
337 ret = EndScene(-1);
338 EXPECT_NE(ret, 0);
339 }
340
341 /**
342 * @tc.name: RtgInterfaceSetMinUtil
343 * @tc.desc: Verify rtg minUtil set function.
344 * @tc.type: FUNC
345 */
346 HWTEST_F(RtgInterfaceTest, RtgInterfaceSetMinUtil, TestSize.Level1)
347 {
348 int ret;
349 int grpId;
350 int pid = getpid();
351 vector<int> pids = {};
352 pids.push_back(pid);
353 grpId = CreateNewRtgGrp(VIP, 0);
354 EXPECT_GT(grpId, 0);
355 ret = AddThreadsToRtg(pids, grpId);
356 EXPECT_EQ(ret, 0);
357 ret = SetMinUtil(0);
358 EXPECT_EQ(ret, 0);
359 ret = DestroyRtgGrp(grpId);
360 EXPECT_EQ(ret, 0);
361 }
362
363 /**
364 * @tc.name: RtgInterfaceSetMinUtilWithNoAddThreadtoGrp
365 * @tc.desc: Verify rtg minUtil set function with NoAddThreadtoGrp.
366 * @tc.type: FUNC
367 */
368 HWTEST_F(RtgInterfaceTest, RtgInterfaceSetMinUtilWithNoAddThreadtoGrp, TestSize.Level1)
369 {
370 int ret;
371 int grpId;
372 grpId = CreateNewRtgGrp(VIP, 0);
373 EXPECT_GT(grpId, 0);
374 ret = SetMinUtil(0);
375 EXPECT_NE(ret, 0);
376 ret = DestroyRtgGrp(grpId);
377 EXPECT_EQ(ret, 0);
378 }
379 /**
380 * @tc.name: RtgInterfaceSetMinUtilWithErrorParam
381 * @tc.desc: Verify rtg minUtil set function with error Parameter.
382 * @tc.type: FUNC
383 */
384 HWTEST_F(RtgInterfaceTest, RtgInterfaceSetMinUtilWithErrorParam, TestSize.Level1)
385 {
386 int ret;
387 ret = SetMinUtil(-1);
388 EXPECT_NE(ret, 0);
389 }
390
391 /**
392 * @tc.name: RtgInterfaceSetMargin
393 * @tc.desc: Verify rtg margin set function.
394 * @tc.type: FUNC
395 */
396 HWTEST_F(RtgInterfaceTest, RtgInterfaceSetMargin, TestSize.Level1)
397 {
398 int ret;
399 int grpId;
400 int pid = getpid();
401 vector<int> pids = {};
402 pids.push_back(pid);
403 grpId = CreateNewRtgGrp(VIP, 0);
404 EXPECT_GT(grpId, 0);
405 ret = AddThreadsToRtg(pids, grpId);
406 EXPECT_EQ(ret, 0);
407 ret = SetMargin(0);
408 EXPECT_EQ(ret, 0);
409 ret = DestroyRtgGrp(grpId);
410 EXPECT_EQ(ret, 0);
411 }
412
413 /**
414 * @tc.name: RtgInterfaceSetMarginWithNoAddThreadtoGrp
415 * @tc.desc: Verify rtg margin set function with NoAddThreadtoGrp.
416 * @tc.type: FUNC
417 */
418 HWTEST_F(RtgInterfaceTest, RtgInterfaceSetMarginWithNoAddThreadtoGrp, TestSize.Level1)
419 {
420 int ret;
421 int grpId;
422 grpId = CreateNewRtgGrp(VIP, 0);
423 EXPECT_GT(grpId, 0);
424 ret = SetMargin(0);
425 EXPECT_NE(ret, 0);
426 ret = DestroyRtgGrp(grpId);
427 EXPECT_EQ(ret, 0);
428 }
429 /**
430 * @tc.name: RtgInterfaceSetMarginWithErrorParam
431 * @tc.desc: Verify rtg margin set function with error parameter.
432 * @tc.type: FUNC
433 */
434 HWTEST_F(RtgInterfaceTest, RtgInterfaceSetMarginWithErrorParam, TestSize.Level1)
435 {
436 int ret;
437 int grpId;
438 grpId = CreateNewRtgGrp(VIP, 0);
439 EXPECT_GT(grpId, 0);
440 ret = SetMargin(-101);
441 EXPECT_NE(ret, 0);
442 ret = SetMargin(65536);
443 EXPECT_NE(ret, 0);
444 ret = DestroyRtgGrp(grpId);
445 EXPECT_EQ(ret, 0);
446 }
447
448
449 /**
450 * @tc.name: RtgInterfaceSetAttr
451 * @tc.desc: Verify rtg attr set function.
452 * @tc.type: FUNC
453 */
454 HWTEST_F(RtgInterfaceTest, RtgInterfaceSetAttr, TestSize.Level1)
455 {
456 int ret;
457 int grpId;
458 grpId = CreateNewRtgGrp(VIP, 0);
459 EXPECT_GT(grpId, 0);
460 ret = SetFrameRateAndPrioType(grpId, 60, VIP);
461 EXPECT_EQ(ret, 0);
462 ret = DestroyRtgGrp(grpId);
463 EXPECT_EQ(ret, 0);
464 }
465
466 /**
467 * @tc.name: RtgInterfaceSetErrorAttr
468 * @tc.desc: Verify rtg attr set function with error attr param.
469 * @tc.type: FUNC
470 */
471 HWTEST_F(RtgInterfaceTest, RtgInterfaceSetErrorAttr, TestSize.Level1)
472 {
473 int ret;
474 int grpId;
475 grpId = CreateNewRtgGrp(VIP, 0);
476 EXPECT_GT(grpId, 0);
477 ret = SetFrameRateAndPrioType(grpId, 0, VIP);
478 EXPECT_NE(ret, 0);
479 ret = SetFrameRateAndPrioType(grpId, -1, VIP);
480 EXPECT_NE(ret, 0);
481 ret = DestroyRtgGrp(grpId);
482 EXPECT_EQ(ret, 0);
483 }
484
485
486 /**
487 * @tc.name: RtgInterfaceAddDestoryMultipleThreads
488 * @tc.desc: Verify rtg multiple add destory function.
489 * @tc.type: FUNC
490 */
491 HWTEST_F(RtgInterfaceTest, RtgInterfaceAddDestoryMultipleThreads, TestSize.Level1)
492 {
493 int ret;
494 int pid[3];
495 vector<int> threads;
496 int grpId;
497 for (int i = 0; i < 3; i++) {
498 pid[i] = fork();
499 ASSERT_TRUE(pid[i] >= 0) << "> parent: fork errno = " << errno;
500 if (pid[i] == 0) {
501 usleep(50000);
502 _Exit(0);
503 }
504 threads.push_back(pid[i]);
505 }
506 grpId = CreateNewRtgGrp(NORMAL_TASK, 0);
507 EXPECT_GT(grpId, 0);
508 ret = AddThreadsToRtg(threads, grpId);
509 EXPECT_EQ(ret, 0);
510 ret = DestroyRtgGrp(grpId);
511 EXPECT_EQ(ret, 0);
512 }
513
514 /**
515 * @tc.name: RtgInterfaceAddDestoryVIPGroupMultipleThreads
516 * @tc.desc: Verify rtg multiple add destory about VIP group function .
517 * @tc.type: FUNC
518 */
519 HWTEST_F(RtgInterfaceTest, RtgInterfaceAddDestoryVIPGroupMultipleThreads, TestSize.Level1)
520 {
521 int ret;
522 int pid[5];
523 vector<int> threads;
524 int grpId;
525 for (int i = 0; i < 5; i++) {
526 pid[i] = fork();
527 ASSERT_TRUE(pid[i] >= 0) << "> parent: fork errno = " << errno;
528 if (pid[i] == 0) {
529 usleep(50000);
530 _Exit(0);
531 }
532 threads.push_back(pid[i]);
533 }
534 grpId = CreateNewRtgGrp(VIP, 0);
535 EXPECT_GT(grpId, 0);
536 ret = AddThreadsToRtg(threads, grpId, 36);
537 EXPECT_EQ(ret, 0);
538 ret = DestroyRtgGrp(grpId);
539 EXPECT_EQ(ret, 0);
540 }
541
542 /**
543 * @tc.name: RtgInterfaceAddDestoryRepeatCalls
544 * @tc.desc: Verify rtg multiple add destory repeat calls .
545 * @tc.type: FUNC
546 */
547 HWTEST_F(RtgInterfaceTest, RtgInterfaceAddDestoryRepeatCalls, TestSize.Level1)
548 {
549 int ret;
550 int pid[4];
551 vector<int> threads;
552 int grpId;
553 for (int i = 0; i < 4; i++) {
554 pid[i] = fork();
555 ASSERT_TRUE(pid[i] >= 0) << "> parent: fork errno = " << errno;
556 if (pid[i] == 0) {
557 usleep(50000);
558 _Exit(0);
559 }
560 threads.push_back(pid[i]);
561 }
562 grpId = CreateNewRtgGrp(VIP, 0);
563 EXPECT_GT(grpId, 0);
564 ret = AddThreadsToRtg(threads, grpId);
565 EXPECT_EQ(ret, 0);
566 ret = AddThreadsToRtg(threads, grpId);
567 EXPECT_NE(ret, 0);
568 ret = DestroyRtgGrp(grpId);
569 EXPECT_EQ(ret, 0);
570 ret = DestroyRtgGrp(grpId);
571 EXPECT_NE(ret, 0);
572 }
573
574 /**
575 * @tc.name: RtgInterfaceAddMultipleThreadsOutOfLimit
576 * @tc.desc: Verify rtg multiple add function with out of limit threads.
577 * @tc.type: FUNC
578 */
579 HWTEST_F(RtgInterfaceTest, RtgInterfaceAddMultipleThreadsOutOfLimit, TestSize.Level1)
580 {
581 int ret;
582 int pid[8];
583 vector<int> threads;
584 int grpId;
585 for (int i = 0; i < 8; i++) {
586 pid[i] = fork();
587 ASSERT_TRUE(pid[i] >= 0) << "> parent: fork errno = " << errno;
588 if (pid[i] == 0) {
589 usleep(50000);
590 _Exit(0);
591 }
592 threads.push_back(pid[i]);
593 }
594 grpId = CreateNewRtgGrp(NORMAL_TASK, 0);
595 EXPECT_GT(grpId, 0);
596 ret = AddThreadsToRtg(threads, grpId);
597 EXPECT_NE(ret, 0);
598 ret = DestroyRtgGrp(grpId);
599 EXPECT_EQ(ret, 0);
600 }
601 } // namespace RME
602 } // namespace OHOS
603