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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceCreateAndDestroy, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceDestroyErrorGroup, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceAddRtg, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceAddErrorThread, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceAddErrorGroup, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceAddRtgs, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceBeginFrameFreq, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceBeginFrameFreqWithNoAddThreadtoGrp, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceBeginFrameFreqWithErrorParam, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceEndFrameFreq, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceEndFrameFreqWithNoAddThreadtoGrp, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceEndFrameFreqWithErrorParam, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceEndScene, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceEndSceneWithErrorGrp, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceSetMinUtil, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceSetMinUtilWithNoAddThreadtoGrp, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceSetMinUtilWithErrorParam, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceSetMargin, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceSetMarginWithNoAddThreadtoGrp, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceSetMarginWithErrorParam, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceSetAttr, TestSize.Level1)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  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceSetErrorAttr, TestSize.Level1)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 = SetFrameRateAndPrioType(grpId, 121, VIP);
482     EXPECT_NE(ret, 0);
483     ret = DestroyRtgGrp(grpId);
484     EXPECT_EQ(ret, 0);
485 }
486 
487 
488 /**
489  * @tc.name: RtgInterfaceAddDestoryMultipleThreads
490  * @tc.desc: Verify rtg multiple add  destory function.
491  * @tc.type: FUNC
492  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceAddDestoryMultipleThreads, TestSize.Level1)493 HWTEST_F(RtgInterfaceTest, RtgInterfaceAddDestoryMultipleThreads, TestSize.Level1)
494 {
495     int ret;
496     int pid[3];
497     vector<int> threads;
498     int grpId;
499     for (int i = 0; i < 3; i++) {
500         pid[i] = fork();
501         ASSERT_TRUE(pid[i] >= 0) << "> parent: fork errno = " << errno;
502         if (pid[i] == 0) {
503             usleep(50000);
504             _Exit(0);
505         }
506         threads.push_back(pid[i]);
507     }
508     grpId = CreateNewRtgGrp(NORMAL_TASK, 0);
509     EXPECT_GT(grpId, 0);
510     ret = AddThreadsToRtg(threads, grpId);
511     EXPECT_EQ(ret, 0);
512     ret = DestroyRtgGrp(grpId);
513     EXPECT_EQ(ret, 0);
514 }
515 
516 /**
517  * @tc.name: RtgInterfaceAddDestoryVIPGroupMultipleThreads
518  * @tc.desc: Verify rtg multiple add destory about VIP group function .
519  * @tc.type: FUNC
520  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceAddDestoryVIPGroupMultipleThreads, TestSize.Level1)521 HWTEST_F(RtgInterfaceTest, RtgInterfaceAddDestoryVIPGroupMultipleThreads, TestSize.Level1)
522 {
523     int ret;
524     int pid[5];
525     vector<int> threads;
526     int grpId;
527     for (int i = 0; i < 5; i++) {
528         pid[i] = fork();
529         ASSERT_TRUE(pid[i] >= 0) << "> parent: fork errno = " << errno;
530         if (pid[i] == 0) {
531             usleep(50000);
532             _Exit(0);
533         }
534         threads.push_back(pid[i]);
535     }
536     grpId = CreateNewRtgGrp(VIP, 0);
537     EXPECT_GT(grpId, 0);
538     ret = AddThreadsToRtg(threads, grpId, 36);
539     EXPECT_EQ(ret, 0);
540     ret = DestroyRtgGrp(grpId);
541     EXPECT_EQ(ret, 0);
542 }
543 
544 /**
545  * @tc.name: RtgInterfaceAddDestoryRepeatCalls
546  * @tc.desc: Verify rtg multiple add destory repeat calls .
547  * @tc.type: FUNC
548  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceAddDestoryRepeatCalls, TestSize.Level1)549 HWTEST_F(RtgInterfaceTest, RtgInterfaceAddDestoryRepeatCalls, TestSize.Level1)
550 {
551     int ret;
552     int pid[4];
553     vector<int> threads;
554     int grpId;
555     for (int i = 0; i < 4; i++) {
556         pid[i] = fork();
557         ASSERT_TRUE(pid[i] >= 0) << "> parent: fork errno = " << errno;
558         if (pid[i] == 0) {
559             usleep(50000);
560             _Exit(0);
561         }
562         threads.push_back(pid[i]);
563     }
564     grpId = CreateNewRtgGrp(VIP, 0);
565     EXPECT_GT(grpId, 0);
566     ret = AddThreadsToRtg(threads, grpId);
567     EXPECT_EQ(ret, 0);
568     ret = AddThreadsToRtg(threads, grpId);
569     EXPECT_NE(ret, 0);
570     ret = DestroyRtgGrp(grpId);
571     EXPECT_EQ(ret, 0);
572     ret = DestroyRtgGrp(grpId);
573     EXPECT_NE(ret, 0);
574 }
575 
576 /**
577  * @tc.name: RtgInterfaceAddMultipleThreadsOutOfLimit
578  * @tc.desc: Verify rtg multiple add function with out of limit threads.
579  * @tc.type: FUNC
580  */
HWTEST_F(RtgInterfaceTest, RtgInterfaceAddMultipleThreadsOutOfLimit, TestSize.Level1)581 HWTEST_F(RtgInterfaceTest, RtgInterfaceAddMultipleThreadsOutOfLimit, TestSize.Level1)
582 {
583     int ret;
584     int pid[8];
585     vector<int> threads;
586     int grpId;
587     for (int i = 0; i < 8; i++) {
588         pid[i] = fork();
589         ASSERT_TRUE(pid[i] >= 0) << "> parent: fork errno = " << errno;
590         if (pid[i] == 0) {
591             usleep(50000);
592             _Exit(0);
593         }
594         threads.push_back(pid[i]);
595     }
596     grpId = CreateNewRtgGrp(NORMAL_TASK, 0);
597     EXPECT_GT(grpId, 0);
598     ret = AddThreadsToRtg(threads, grpId);
599     EXPECT_NE(ret, 0);
600     ret = DestroyRtgGrp(grpId);
601     EXPECT_EQ(ret, 0);
602 }
603 } // namespace RME
604 } // namespace OHOS
605