1 /*
2  * Copyright (c) 2022 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 <cstdlib>
17 #include <cstring>
18 #include <fcntl.h>
19 #include <gtest/gtest.h>
20 #include <iostream>
21 #include <sys/ioctl.h>
22 #include <sys/utsname.h>
23 #include <unistd.h>
24 #include "cpp/qos_convert.h"
25 #if defined(QOS_FRAME_RTG)
26 #include "concurrent_task_client.h"
27 #endif
28 #include "eu/qos_interface.h"
29 #include "common.h"
30 
31 namespace OHOS {
32 namespace FFRT_TEST {
33 using namespace testing;
34 #ifdef HWTEST_TESTING_EXT_ENABLE
35 using namespace testing::ext;
36 #endif
37 using namespace OHOS::FFRT_TEST;
38 using namespace ffrt;
39 using namespace std;
40 #if defined(QOS_FRAME_RTG)
41 using namespace OHOS::ConcurrentTask;
42 #endif
43 
44 #define QOS_CTRL_SET_QOS_THREAD _IOWR('q', 2, struct TaskConfig)
45 
46 struct TaskConfig {
47     int32_t pid;
48     int32_t value;
49 };
50 
51 const string QOS_CTRL_FILE_PATH = "/dev/qos_sched_ctrl";
52 const int NR_QOS_LEVEL = 9;
53 constexpr int ERROR_NUM = -1;
54 
55 class QosConvertTest : public testing::Test {
56 public:
IsLinuxOs()57     bool IsLinuxOs()
58     {
59         struct utsname nameData;
60         uname(&nameData);
61         int cmpNum = 5;
62         return strncmp(nameData.sysname, "Linux", cmpNum) == 0 ? true : false;
63     }
64 
65 protected:
SetUpTestCase()66     static void SetUpTestCase()
67     {
68     }
69 
TearDownTestCase()70     static void TearDownTestCase()
71     {
72     }
73 
SetUp()74     virtual void SetUp()
75     {
76     }
77 
TearDown()78     virtual void TearDown()
79     {
80     }
81 };
82 
SetRssQos(int level)83 static int SetRssQos(int level)
84 {
85     int tid = gettid();
86     if (level < -1 || level > 9) {
87         return ERROR_NUM;
88     }
89     int32_t handle = open(QOS_CTRL_FILE_PATH.c_str(), (O_RDWR | O_CLOEXEC));
90     if (handle <= 0) {
91         printf("invalid handle %d\n", static_cast<int>(handle));
92         return ERROR_NUM;
93     }
94 
95     struct TaskConfig threadData = {tid, level};
96     int ret = ioctl(handle, QOS_CTRL_SET_QOS_THREAD, &threadData);
97     if (ret != 0) {
98         printf("ioctl setQos failed\n");
99         return ERROR_NUM;
100     }
101 
102     return ret;
103 }
104 
QosTransfer(int qos)105 static int QosTransfer(int qos)
106 {
107     switch (qos) {
108         case 9:
109         case 8:
110         case 7: return 5;
111         case 6: return 4;
112         case 5:
113         case 4: return 3;
114         case 3: return 2;
115         case 2: return 1;
116         case 1: return 0;
117         default:
118             return -1;
119     }
120 }
121 
122 #ifndef FFRT_GITEE
HWTEST_F(QosConvertTest, GetStaticQos1, TestSize.Level1)123 HWTEST_F(QosConvertTest, GetStaticQos1, TestSize.Level1)
124 {
125     for (int i = 1; i <= NR_QOS_LEVEL; i++) {
126         qos tmpQos = qos_default;
127         SetRssQos(i);
128         int ret = GetStaticQos(tmpQos);
129         if (!IsLinuxOs()) {
130             return;
131         }
132         EXPECT_EQ(ret, 0);
133         EXPECT_EQ(tmpQos, QosTransfer(i));
134     }
135 }
136 #endif
137 
HWTEST_F(QosConvertTest, GetStaticQos2, TestSize.Level1)138 HWTEST_F(QosConvertTest, GetStaticQos2, TestSize.Level1)
139 {
140     qos tmpQos = qos_default;
141     SetRssQos(-1);
142     int ret = GetStaticQos(tmpQos);
143     EXPECT_EQ(tmpQos, qos_default);
144     EXPECT_EQ(ret, -1);
145 
146     SetRssQos(0);
147     ret = GetStaticQos(tmpQos);
148     EXPECT_EQ(tmpQos, qos_default);
149     EXPECT_EQ(ret, -1);
150 
151     SetRssQos(10);
152     ret = GetStaticQos(tmpQos);
153     EXPECT_EQ(tmpQos, qos_default);
154     EXPECT_EQ(ret, -1);
155 
156     SetRssQos(-2);
157     ret = GetStaticQos(tmpQos);
158     EXPECT_EQ(tmpQos, qos_default);
159     EXPECT_EQ(ret, -1);
160 }
161 
HWTEST_F(QosConvertTest, GetDynamicQos, TestSize.Level1)162 HWTEST_F(QosConvertTest, GetDynamicQos, TestSize.Level1)
163 {
164 #if defined(QOS_FRAME_RTG)
165     SetRssQos(8);
166     qos tmpQos = qos_default;
167     int ret = GetDynamicQos(tmpQos);
168     IntervalReply rs;
169     ConcurrentTaskClient::GetInstance().QueryInterval(QUERY_RENDER_SERVICE, rs);
170     EXPECT_EQ(tmpQos, qos_default);
171 #endif
172 }
173 
174 #ifndef FFRT_GITEE
HWTEST_F(QosConvertTest, FFRTQosGetInterface, TestSize.Level1)175 HWTEST_F(QosConvertTest, FFRTQosGetInterface, TestSize.Level1)
176 {
177     SetRssQos(8);
178     struct QosCtrlData data;
179     int ret = FFRTQosGet(data);
180     if (!IsLinuxOs()) {
181         return;
182     }
183     EXPECT_EQ(data.staticQos, 5);
184     EXPECT_EQ(ret, 0);
185 }
186 
HWTEST_F(QosConvertTest, FFRTQosGetForOtherInterface, TestSize.Level1)187 HWTEST_F(QosConvertTest, FFRTQosGetForOtherInterface, TestSize.Level1)
188 {
189     SetRssQos(8);
190     struct QosCtrlData data;
191     int ret = FFRTQosGetForOther(gettid(), data);
192     if (!IsLinuxOs()) {
193         return;
194     }
195     EXPECT_EQ(data.staticQos, 5);
196     EXPECT_EQ(ret, 0);
197 }
198 #endif
199 }
200 }