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 #include <climits>
16 #include <iostream>
17 #include <unistd.h>
18 
19 #include "cpu_collector.h"
20 
21 #include <gtest/gtest.h>
22 
23 using namespace testing::ext;
24 using namespace OHOS::HiviewDFX;
25 using namespace OHOS::HiviewDFX::UCollectUtil;
26 using namespace OHOS::HiviewDFX::UCollect;
27 
28 class CpuCollectorTest : public testing::Test {
29 public:
SetUp()30     void SetUp() {};
TearDown()31     void TearDown() {};
SetUpTestCase()32     static void SetUpTestCase() {};
TearDownTestCase()33     static void TearDownTestCase() {};
34 };
35 
36 /**
37  * @tc.name: CpuCollectorTest001
38  * @tc.desc: used to test CpuCollector.CollectSysCpuLoad
39  * @tc.type: FUNC
40 */
41 HWTEST_F(CpuCollectorTest, CpuCollectorTest001, TestSize.Level1)
42 {
43     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
44     CollectResult<SysCpuLoad> result = collector->CollectSysCpuLoad();
45     std::cout << "collect system cpu load result=" << result.retCode << std::endl;
46     ASSERT_TRUE(result.retCode == UcError::SUCCESS);
47 
48     const SysCpuLoad& sysCpuLoad = result.data;
49     std::cout << "collect system cpu load, avgLoad1=" << sysCpuLoad.avgLoad1 << std::endl;
50     std::cout << "collect system cpu load, avgLoad5=" << sysCpuLoad.avgLoad5 << std::endl;
51     std::cout << "collect system cpu load, avgLoad15=" << sysCpuLoad.avgLoad15 << std::endl;
52     ASSERT_TRUE(sysCpuLoad.avgLoad1 > 0);
53     ASSERT_TRUE(sysCpuLoad.avgLoad5 > 0);
54     ASSERT_TRUE(sysCpuLoad.avgLoad15 > 0);
55 }
56 
57 /**
58  * @tc.name: CpuCollectorTest002
59  * @tc.desc: used to test CpuCollector.CollectSysCpuUsage with updating
60  * @tc.type: FUNC
61 */
62 HWTEST_F(CpuCollectorTest, CpuCollectorTest002, TestSize.Level1)
63 {
64     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
65 
66     // first collection
67     sleep(1); // 1s
68     CollectResult<SysCpuUsage> result = collector->CollectSysCpuUsage(true);
69     std::cout << "collect1 system cpu usage result=" << result.retCode << std::endl;
70     ASSERT_TRUE(result.retCode == UcError::SUCCESS);
71 
72     const SysCpuUsage& sysCpuUsage = result.data;
73     ASSERT_GT(sysCpuUsage.startTime, 0);
74     ASSERT_GT(sysCpuUsage.endTime, sysCpuUsage.startTime);
75     ASSERT_GT(sysCpuUsage.cpuInfos.size(), 0);
76     for (const auto& cpuInfo : sysCpuUsage.cpuInfos) {
77         std::cout << cpuInfo.cpuId << ", userUsage=" << cpuInfo.userUsage
78             << ", niceUsage=" << cpuInfo.niceUsage
79             << ", systemUsage=" << cpuInfo.systemUsage
80             << ", idleUsage=" << cpuInfo.idleUsage
81             << ", ioWaitUsage=" << cpuInfo.ioWaitUsage
82             << ", irqUsage=" << cpuInfo.irqUsage
83             << ", softIrqUsage=" << cpuInfo.softIrqUsage
84             << std::endl;
85         ASSERT_FALSE(cpuInfo.cpuId.empty());
86     }
87 
88     // second collection
89     sleep(1); // 1s
90     CollectResult<SysCpuUsage> nextResult = collector->CollectSysCpuUsage(true);
91     std::cout << "collect2 system cpu usage result=" << nextResult.retCode << std::endl;
92     ASSERT_TRUE(nextResult.retCode == UcError::SUCCESS);
93     ASSERT_EQ(nextResult.data.startTime, sysCpuUsage.endTime);
94     ASSERT_GT(nextResult.data.endTime, nextResult.data.startTime);
95     ASSERT_EQ(nextResult.data.cpuInfos.size(), sysCpuUsage.cpuInfos.size());
96 }
97 
98 /**
99  * @tc.name: CpuCollectorTest003
100  * @tc.desc: used to test CpuCollector.CollectSysCpuUsage without updating
101  * @tc.type: FUNC
102 */
103 HWTEST_F(CpuCollectorTest, CpuCollectorTest003, TestSize.Level1)
104 {
105     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
106 
107     // first collection
108     sleep(1); // 1s
109     CollectResult<SysCpuUsage> result = collector->CollectSysCpuUsage(false);
110     std::cout << "collect1 system cpu usage result=" << result.retCode << std::endl;
111     ASSERT_TRUE(result.retCode == UcError::SUCCESS);
112 
113     // second collection
114     sleep(1); // 1s
115     CollectResult<SysCpuUsage> nextResult = collector->CollectSysCpuUsage(false);
116     std::cout << "collect2 system cpu usage result=" << nextResult.retCode << std::endl;
117     ASSERT_TRUE(nextResult.retCode == UcError::SUCCESS);
118     ASSERT_EQ(nextResult.data.startTime, result.data.startTime);
119     ASSERT_GT(nextResult.data.endTime, result.data.endTime);
120     ASSERT_EQ(nextResult.data.cpuInfos.size(), result.data.cpuInfos.size());
121 }
122 
123 /**
124  * @tc.name: CpuCollectorTest004
125  * @tc.desc: used to test CpuCollector.CollectCpuFrequency
126  * @tc.type: FUNC
127 */
128 HWTEST_F(CpuCollectorTest, CpuCollectorTest004, TestSize.Level1)
129 {
130     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
131     CollectResult<std::vector<CpuFreq>> result = collector->CollectCpuFrequency();
132     std::cout << "collect system cpu frequency result=" << result.retCode << std::endl;
133     ASSERT_TRUE(result.retCode == UcError::SUCCESS);
134 
135     const std::vector<CpuFreq>& cpuFreqs = result.data;
136     std::cout << "collect system cpu frequency, size=" << cpuFreqs.size() << std::endl;
137     ASSERT_GT(cpuFreqs.size(), 0);
138     for (size_t i = 0; i < cpuFreqs.size(); ++i) {
139         std::cout << "cpu" << cpuFreqs[i].cpuId << ", curFreq=" << cpuFreqs[i].curFreq << ", minFreq="
140             << cpuFreqs[i].minFreq << ", maxFreq=" << cpuFreqs[i].maxFreq << std::endl;
141         ASSERT_EQ(cpuFreqs[i].cpuId, i);
142         ASSERT_GT(cpuFreqs[i].curFreq, 0);
143         ASSERT_GT(cpuFreqs[i].minFreq, 0);
144         ASSERT_GT(cpuFreqs[i].maxFreq, 0);
145     }
146 }
147 
148 /**
149  * @tc.name: CpuCollectorTest009
150  * @tc.desc: used to test CpuCollector.CollectProcessCpuStatInfo
151  * @tc.type: FUNC
152 */
153 HWTEST_F(CpuCollectorTest, CpuCollectorTest009, TestSize.Level1)
154 {
155     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
156     constexpr int initPid = 1;
157     auto collectResult = collector->CollectProcessCpuStatInfo(initPid);
158     ASSERT_TRUE(collectResult.retCode == UcError::SUCCESS);
159 
160     std::cout << "proc.procName=" << collectResult.data.procName << std::endl;
161     std::cout << "proc.startTime=" << collectResult.data.startTime << std::endl;
162     std::cout << "proc.endTime=" << collectResult.data.endTime << std::endl;
163     std::cout << "proc.pid=" << collectResult.data.pid << std::endl;
164     std::cout << "proc.minFlt=" << collectResult.data.minFlt << std::endl;
165     std::cout << "proc.majFlt=" << collectResult.data.majFlt << std::endl;
166     std::cout << "proc.cpuLoad=" << collectResult.data.cpuLoad << std::endl;
167     std::cout << "proc.uCpuUsage=" << collectResult.data.uCpuUsage << std::endl;
168     std::cout << "proc.sCpuUsage=" << collectResult.data.sCpuUsage << std::endl;
169     std::cout << "proc.cpuUsage=" << collectResult.data.cpuUsage << std::endl;
170     ASSERT_GT(collectResult.data.startTime, 0);
171     ASSERT_GT(collectResult.data.endTime, 0);
172     ASSERT_EQ(collectResult.data.pid, initPid);
173     ASSERT_GE(collectResult.data.minFlt, 0);
174     ASSERT_GE(collectResult.data.majFlt, 0);
175     ASSERT_GE(collectResult.data.cpuLoad, 0);
176     ASSERT_GE(collectResult.data.uCpuUsage, 0);
177     ASSERT_GE(collectResult.data.sCpuUsage, 0);
178     ASSERT_GE(collectResult.data.cpuUsage, 0);
179     ASSERT_FALSE(collectResult.data.procName.empty());
180 
181     sleep(1); // 1s
182     auto nextCollectResult = collector->CollectProcessCpuStatInfo(initPid);
183     ASSERT_TRUE(nextCollectResult.retCode == UcError::SUCCESS);
184     ASSERT_EQ(nextCollectResult.data.startTime, collectResult.data.startTime);
185     ASSERT_GT(nextCollectResult.data.endTime, collectResult.data.endTime);
186 }
187 
188 /**
189  * @tc.name: CpuCollectorTest010
190  * @tc.desc: used to test CpuCollector.CollectProcessCpuStatInfo
191  * @tc.type: FUNC
192 */
193 HWTEST_F(CpuCollectorTest, CpuCollectorTest010, TestSize.Level1)
194 {
195     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
196     constexpr int notExistPid = INT_MAX;
197     auto collectResult = collector->CollectProcessCpuStatInfo(notExistPid);
198     ASSERT_TRUE(collectResult.retCode != UcError::SUCCESS);
199 }
200 
201 /**
202  * @tc.name: CpuCollectorTest011
203  * @tc.desc: used to test CpuCollector.CollectProcessCpuStatInfo
204  * @tc.type: FUNC
205 */
206 HWTEST_F(CpuCollectorTest, CpuCollectorTest011, TestSize.Level1)
207 {
208     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
209     constexpr int invalidPid = -1;
210     auto collectResult = collector->CollectProcessCpuStatInfo(invalidPid);
211     ASSERT_TRUE(collectResult.retCode != UcError::SUCCESS);
212 }
213 
214 /**
215  * @tc.name: CpuCollectorTest012
216  * @tc.desc: used to test CpuCollector.CollectProcessCpuStatInfos
217  * @tc.type: FUNC
218 */
219 HWTEST_F(CpuCollectorTest, CpuCollectorTest012, TestSize.Level1)
220 {
221     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
222     auto collectResult = collector->CollectProcessCpuStatInfos(true);
223     ASSERT_TRUE(collectResult.retCode == UcError::SUCCESS);
224     ASSERT_FALSE(collectResult.data.empty());
225 
226     sleep(1); // 1s
227     auto nextCollectResult = collector->CollectProcessCpuStatInfos();
228     ASSERT_TRUE(nextCollectResult.retCode == UcError::SUCCESS);
229     ASSERT_FALSE(nextCollectResult.data.empty());
230 
231     std::cout << "next collection startTime=" << nextCollectResult.data[0].startTime << std::endl;
232     std::cout << "next collection endTime=" << nextCollectResult.data[0].endTime << std::endl;
233     ASSERT_EQ(nextCollectResult.data[0].startTime, collectResult.data[0].endTime);
234     ASSERT_GT(nextCollectResult.data[0].endTime, nextCollectResult.data[0].startTime);
235 }
236 
237 /**
238  * @tc.name: CpuCollectorTest013
239  * @tc.desc: used to test CpuCollector.CollectProcessCpuStatInfos
240  * @tc.type: FUNC
241 */
242 HWTEST_F(CpuCollectorTest, CpuCollectorTest013, TestSize.Level1)
243 {
244     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
245     auto collectResult = collector->CollectProcessCpuStatInfos(true);
246     ASSERT_TRUE(collectResult.retCode == UcError::SUCCESS);
247     ASSERT_FALSE(collectResult.data.empty());
248 
249     sleep(1); // 1s
250     auto nextCollectResult = collector->CollectProcessCpuStatInfos(true);
251     ASSERT_TRUE(nextCollectResult.retCode == UcError::SUCCESS);
252     ASSERT_FALSE(nextCollectResult.data.empty());
253 
254     ASSERT_GT(nextCollectResult.data[0].startTime, collectResult.data[0].startTime);
255     ASSERT_GT(nextCollectResult.data[0].endTime, collectResult.data[0].endTime);
256 }
257 
258 /**
259  * @tc.name: CpuCollectorTest014
260  * @tc.desc: used to test CpuCollector.CollectProcessCpuStatInfos
261  * @tc.type: FUNC
262 */
263 HWTEST_F(CpuCollectorTest, CpuCollectorTest014, TestSize.Level1)
264 {
265     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
266     auto firstCollectResult = collector->CollectProcessCpuStatInfos(false);
267     ASSERT_TRUE(firstCollectResult.retCode == UcError::SUCCESS);
268     ASSERT_FALSE(firstCollectResult.data.empty());
269 
270     sleep(1); // 1s
271     auto secondCollectResult = collector->CollectProcessCpuStatInfos(false);
272     ASSERT_TRUE(secondCollectResult.retCode == UcError::SUCCESS);
273     ASSERT_FALSE(secondCollectResult.data.empty());
274 
275     ASSERT_EQ(firstCollectResult.data[0].startTime, secondCollectResult.data[0].startTime);
276     ASSERT_LT(firstCollectResult.data[0].endTime, secondCollectResult.data[0].endTime);
277 }
278 
279 /**
280  * @tc.name: CpuCollectorTest015
281  * @tc.desc: used to test the update function of CpuCollector.CollectProcessCpuStatInfo
282  * @tc.type: FUNC
283 */
284 HWTEST_F(CpuCollectorTest, CpuCollectorTest015, TestSize.Level1)
285 {
286     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
287     constexpr int initPid = 1;
288     auto collectResult = collector->CollectProcessCpuStatInfo(initPid, true);
289     ASSERT_TRUE(collectResult.retCode == UcError::SUCCESS);
290 
291     sleep(1); // 1s
292     auto nextCollectResult = collector->CollectProcessCpuStatInfo(initPid, true);
293     ASSERT_TRUE(nextCollectResult.retCode == UcError::SUCCESS);
294 
295     std::cout << "first collection startTime=" << collectResult.data.startTime << std::endl;
296     std::cout << "first collection endTime=" << collectResult.data.endTime << std::endl;
297     std::cout << "next collection startTime=" << nextCollectResult.data.startTime << std::endl;
298     std::cout << "next collection endTime=" << nextCollectResult.data.endTime << std::endl;
299     ASSERT_EQ(nextCollectResult.data.startTime, collectResult.data.endTime);
300     ASSERT_GT(nextCollectResult.data.endTime, collectResult.data.endTime);
301 }
302 
303 /**
304  * @tc.name: CpuCollectorTest016
305  * @tc.desc: used to test the function of CpuCollector.GetSysCpuUsage;
306  * @tc.type: FUNC
307 */
308 HWTEST_F(CpuCollectorTest, CpuCollectorTest016, TestSize.Level1)
309 {
310     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
311     auto collectResult = collector->GetSysCpuUsage();
312     ASSERT_TRUE(collectResult.retCode == UcError::SUCCESS);
313     ASSERT_TRUE(collectResult.data >= 0 && collectResult.data <= 1);
314 }
315 
316 /**
317  * @tc.name: CpuCollectorTest017
318  * @tc.desc: used to test the function of CreateThreadStatInfoCollector with self pid;
319  * @tc.type: FUNC
320 */
321 HWTEST_F(CpuCollectorTest, CpuCollectorTest017, TestSize.Level1)
322 {
323     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
324     auto threadCollector = collector->CreateThreadCollector(getpid());
325     sleep(1);
326     auto collectResult1 = threadCollector->CollectThreadStatInfos();
327     ASSERT_TRUE(collectResult1.retCode == UcError::SUCCESS);
328     sleep(1);
329     auto collectResult2 = threadCollector->CollectThreadStatInfos(true);
330     ASSERT_TRUE(collectResult2.retCode == UcError::SUCCESS);
331     ASSERT_TRUE(collectResult2.data.size() >= 1);
332     ASSERT_TRUE(collectResult2.data[0].cpuUsage >= 0);
333     ASSERT_TRUE(collectResult1.data[0].startTime == collectResult2.data[0].startTime);
334     sleep(1);
335     auto collectResult3 = threadCollector->CollectThreadStatInfos();
336     ASSERT_TRUE(collectResult3.retCode == UcError::SUCCESS);
337     ASSERT_TRUE(collectResult3.data.size() >= 1);
338     ASSERT_TRUE(collectResult3.data[0].cpuUsage >= 0);
339     ASSERT_TRUE(collectResult2.data[0].endTime == collectResult3.data[0].startTime);
340 }
341 
342 /**
343  * @tc.name: CpuCollectorTest018
344  * @tc.desc: used to test the function of CreateThreadStatInfoCollector with other pid;
345  * @tc.type: FUNC
346 */
347 HWTEST_F(CpuCollectorTest, CpuCollectorTest018, TestSize.Level1)
348 {
349     std::shared_ptr<CpuCollector> collector = CpuCollector::Create();
350     auto threadCollector = collector->CreateThreadCollector(1);
351     sleep(1);
352     auto collectResult1 = threadCollector->CollectThreadStatInfos(true);
353     ASSERT_TRUE(collectResult1.retCode == UcError::SUCCESS);
354     sleep(1);
355     auto collectResult2 = threadCollector->CollectThreadStatInfos(false);
356     ASSERT_TRUE(collectResult2.retCode == UcError::SUCCESS);
357     ASSERT_TRUE(collectResult2.data.size() >= 1);
358     ASSERT_TRUE(collectResult2.data[0].cpuUsage >= 0);
359     ASSERT_TRUE(collectResult1.data[0].endTime == collectResult2.data[0].startTime);
360     sleep(1);
361     auto collectResult3 = threadCollector->CollectThreadStatInfos();
362     ASSERT_TRUE(collectResult3.retCode == UcError::SUCCESS);
363     ASSERT_TRUE(collectResult3.data.size() >= 1);
364     ASSERT_TRUE(collectResult3.data[0].cpuUsage >= 0);
365     ASSERT_TRUE(collectResult2.data[0].startTime == collectResult3.data[0].startTime);
366 }
367 
368 /**
369  * @tc.name: CpuCollectorTest019
370  * @tc.desc: used to test the function of CpuCollector.Create;
371  * @tc.type: FUNC
372 */
373 HWTEST_F(CpuCollectorTest, CpuCollectorTest019, TestSize.Level1)
374 {
375     std::shared_ptr<CpuCollector> collector1 = CpuCollector::Create();
376     ASSERT_NE(collector1, nullptr);
377     std::shared_ptr<CpuCollector> collector2 = CpuCollector::Create();
378     ASSERT_NE(collector2, nullptr);
379     ASSERT_EQ(collector1, collector2);
380 
381     std::shared_ptr<CpuCollector> collector3 = CpuCollector::Create(false);
382     ASSERT_NE(collector3, nullptr);
383     std::shared_ptr<CpuCollector> collector4 = CpuCollector::Create(false);
384     ASSERT_NE(collector4, nullptr);
385     ASSERT_NE(collector3, collector4);
386 }
387