1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
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 <cinttypes>
16 #include <gtest/gtest.h>
17 #include <dlfcn.h>
18
19 #include "cpu_data_plugin.h"
20 #include "plugin_module_api.h"
21
22 using namespace testing::ext;
23
24 namespace {
25 const std::string DEFAULT_TEST_PATH = "/data/local/tmp/resources";
26 const std::string SO_PATH = "libcpudataplugin.z.so";
27 const std::string DEFAULT_BIN_PATH("/data/local/tmp/cpudataplugintest");
28 constexpr uint32_t BUF_SIZE = 4 * 1024 * 1024;
29 constexpr int TEST_PID = 1;
30
31 std::string g_path;
32 std::string g_testPath;
33 std::vector<int> g_tidList = {1872, 1965, 1966, 1967, 1968, 1995, 1996};
34
35 constexpr int CORE_NUM = 6;
36 constexpr int THREAD_NUM = 7;
37 constexpr int FIRST_THREAD_NUM = 5;
38 constexpr int SECOND_THREAD_NUM = 6;
39 const int PERCENT = 100;
40
41 struct TestSystemStat {
42 int32_t core;
43 int64_t user;
44 int64_t nice;
45 int64_t system;
46 int64_t idle;
47 int64_t iowait;
48 int64_t irq;
49 int64_t softirq;
50 int64_t steal;
51 };
52
53 struct TestCpuUsage {
54 double userLoad;
55 double sysLoad;
56 double totalLoad;
57 };
58
59 struct TestStat {
60 int64_t utime;
61 int64_t stime;
62 int64_t cutime;
63 int64_t cstime;
64 };
65
66 struct TestTidStat {
67 int32_t tid;
68 std::string name;
69 ThreadState state;
70 TestStat stat;
71 };
72
73 struct TestFreq {
74 int32_t curFreq;
75 int32_t maxFreq;
76 int32_t minFreq;
77 };
78
79 TestSystemStat g_systemStat[CORE_NUM + 1] = {
80 {-1, 24875428, 3952448, 11859815, 1193297105, 8980661, 0, 2607250, 0},
81 {0, 4165400, 662862, 1966195, 196987024, 3571925, 0, 817371, 0},
82 {1, 3861506, 676578, 1702753, 199535158, 1752008, 0, 401639, 0},
83 {2, 3549890, 676286, 1544630, 200640747, 1133743, 0, 205972, 0},
84 {3, 3336646, 676939, 1458898, 201176432, 854578, 0, 124812, 0},
85 {4, 4566158, 601107, 2305309, 197166395, 929594, 0, 1007959, 0},
86 {5, 5395826, 658673, 2882028, 197791346, 738811, 0, 49496, 0},
87 };
88 TestSystemStat g_systemStat1[CORE_NUM + 1] = {
89 {-1, 1234567, 2345678, 1111111, 1193291234, 3546789, 0, 2345678, 0},
90 {0, 2345678, 662862, 1966195, 1111111, 3571925, 0, 817371, 0},
91 {1, 3861506, 2345678, 1702753, 199535158, 1752008, 0, 401639, 0},
92 {2, 3549890, 1111111, 2345678, 1234567, 1133743, 0, 205972, 0},
93 {3, 3336646, 676939, 1458898, 2345678, 854578, 0, 2345678, 0},
94 {4, 1111111, 601107, 2305309, 3546789, 929594, 0, 1007959, 0},
95 {5, 3546789, 658673, 1234567, 197791346, 738811, 0, 49496, 0},
96 };
97 TestSystemStat g_systemStat2[CORE_NUM + 1] = {
98 {-1, 3546789, 2345678, 1111111, 1193291234, 3546789, 0, 2345678, 0},
99 {0, 3546789, 662862, 1966195, 2345678, 3571925, 0, 817371, 0},
100 {1, 3861506, 1111111, 1702753, 199535158, 1752008, 0, 401639, 0},
101 {2, 3549890, 2345678, 2345678, 3546789, 1111111, 0, 205972, 0},
102 {3, 3336646, 676939, 1458898, 2345678, 854578, 0, 2345678, 0},
103 {4, 2345678, 601107, 2305309, 3546789, 929594, 0, 1111111, 0},
104 {5, 3546789, 658673, 3546789, 197791346, 738811, 0, 49496, 0},
105 };
106
107 TestStat g_pidStat = {60, 10, 20, 30};
108 TestStat g_pidStat1 = {50, 10, 40, 10};
109 TestStat g_pidStat2 = {70, 0, 10, 20};
110
111 TestTidStat g_tidStat[THREAD_NUM] = {
112 {1872, "ibus-x11", THREAD_RUNNING, {17, 5, 10, 10}},
113 {1965, "ibus-x1:disk$0", THREAD_SLEEPING, {8, 1, 5, 8}},
114 {1966, "ibus-x1:disk$1", THREAD_UNSPECIFIED, {0, 0, 0, 0}},
115 {1967, "ibus-x1:disk$2", THREAD_SLEEPING, {10, 1, 5, 8}},
116 {1968, "ibus-x1:disk$3", THREAD_STOPPED, {7, 0, 0, 0}},
117 {1995, "gmain", THREAD_SLEEPING, {15, 3, 0, 4}},
118 {1996, "gdbus", THREAD_WAITING, {5, 0, 0, 0}},
119 };
120 TestTidStat g_tidStat1[THREAD_NUM] = {
121 {1209, "skytone:service", THREAD_RUNNING, {22, 8, 0, 0}},
122 {1646, "Jit thread pool", THREAD_UNSPECIFIED, {2, 1, 0, 0}},
123 {1654, "Signal Catcher", THREAD_STOPPED, {1, 0, 0, 0}},
124 {1655, "HeapTaskDaemon", THREAD_SLEEPING, {3, 0, 0, 0}},
125 {1656, "ReferenceQueueD", THREAD_WAITING, {0, 0, 0, 0}},
126 };
127 TestTidStat g_tidStat2[THREAD_NUM] = {
128 {1662, "FinalizerDaemon", THREAD_STOPPED, {0, 0, 0, 0}},
129 {1663, "FinalizerWatchd", THREAD_RUNNING, {0, 0, 0, 0}},
130 {1666, "Binder:1209_1", THREAD_RUNNING, {0, 0, 0, 0}},
131 {1679, "Binder:1209_2", THREAD_UNSPECIFIED, {0, 0, 0, 0}},
132 {1680, "Binder:1209_3", THREAD_WAITING, {54, 8, 0, 0}},
133 {1681, "Binder:1209_4", THREAD_SLEEPING, {0, 0, 0, 0}},
134 };
135
136 TestFreq g_freq[CORE_NUM + 1] = {
137 {1018000, 3844000, 509000}, {1023000, 2844000, 509000},
138 {1011000, 3844000, 509000}, {1518000, 3844000, 1018000},
139 {1245000, 1844000, 1018000}, {1767000, 3044000, 1018000},
140 };
141
142 class CpuDataPluginTest : public ::testing::Test {
143 public:
SetUpTestCase()144 static void SetUpTestCase() {}
145
TearDownTestCase()146 static void TearDownTestCase()
147 {
148 if (access(g_testPath.c_str(), F_OK) == 0) {
149 std::string str = "rm -rf " + g_testPath;
150 system(str.c_str());
151 }
152 }
153 };
154
Getexepath()155 string Getexepath()
156 {
157 char buf[PATH_MAX] = "";
158 std::string path = "/proc/self/exe";
159 size_t rslt = readlink(path.c_str(), buf, sizeof(buf));
160 if (rslt < 0 || (rslt >= sizeof(buf))) {
161 return "";
162 }
163 buf[rslt] = '\0';
164 for (int i = rslt; i >= 0; i--) {
165 if (buf[i] == '/') {
166 buf[i + 1] = '\0';
167 break;
168 }
169 }
170 return buf;
171 }
172
GetFullPath(std::string path)173 std::string GetFullPath(std::string path)
174 {
175 if (path.size() > 0 && path[0] != '/') {
176 return Getexepath() + path;
177 }
178 return path;
179 }
180
CheckTid(std::vector<int> & tidListTmp)181 bool CheckTid(std::vector<int>& tidListTmp)
182 {
183 sort(g_tidList.begin(), g_tidList.end());
184 for (size_t i = 0; i < g_tidList.size(); i++) {
185 if (tidListTmp.at(i) != g_tidList.at(i)) {
186 return false;
187 }
188 }
189 return true;
190 }
191
PluginCpuinfoStub(CpuDataPlugin & cpuPlugin,CpuData & cpuData,int pid,bool reportProcess,bool unusualBuff,bool skipThread=false)192 bool PluginCpuinfoStub(CpuDataPlugin& cpuPlugin, CpuData& cpuData, int pid, bool reportProcess, bool unusualBuff,
193 bool skipThread = false)
194 {
195 CpuConfig protoConfig;
196 protoConfig.set_pid(pid);
197 if (reportProcess) {
198 protoConfig.set_report_process_info(true);
199 }
200 if (skipThread) {
201 protoConfig.set_skip_thread_cpu_info(true);
202 }
203
204 // serialize
205 std::vector<uint8_t> configData(protoConfig.ByteSizeLong());
206 int ret = protoConfig.SerializeToArray(configData.data(), configData.size());
207
208 // start
209 ret = cpuPlugin.Start(configData.data(), configData.size());
210 if (ret < 0) {
211 return false;
212 }
213
214 // report
215 std::vector<uint8_t> bufferData(BUF_SIZE);
216 if (unusualBuff) { // buffer异常,调整缓冲区长度为1,测试异常情况
217 bufferData.resize(1, 0);
218 }
219
220 ret = cpuPlugin.Report(bufferData.data(), bufferData.size());
221 if (ret > 0) {
222 cpuData.ParseFromArray(bufferData.data(), ret);
223 return true;
224 }
225
226 return false;
227 }
228
GetSystemCpuTime(TestSystemStat & stat,int64_t Hz,int64_t & usageTime,int64_t & time)229 void GetSystemCpuTime(TestSystemStat& stat, int64_t Hz, int64_t& usageTime, int64_t& time)
230 {
231 usageTime = (stat.user + stat.nice + stat.system + stat.irq + stat.softirq + stat.steal) * Hz;
232 time = usageTime + (stat.idle + stat.iowait) * Hz;
233 }
234
GetCpuUsage(TestCpuUsage & cpuUsage,int64_t Hz)235 void GetCpuUsage(TestCpuUsage& cpuUsage, int64_t Hz)
236 {
237 TestSystemStat stat = g_systemStat[0];
238 int64_t userTime = stat.user * Hz;
239 int64_t sysTime = stat.system * Hz;
240 int64_t totalTime = (stat.user + stat.nice + stat.system + stat.irq + stat.softirq + stat.steal) * Hz;
241 int64_t bootTime = totalTime + (stat.idle + stat.iowait) * Hz;
242 cpuUsage.userLoad = (static_cast<double>(userTime) / bootTime) * PERCENT;
243 cpuUsage.sysLoad = (static_cast<double>(sysTime) / bootTime) * PERCENT;
244 cpuUsage.totalLoad = (static_cast<double>(totalTime) / bootTime) * PERCENT;
245 }
246
247 /**
248 * @tc.name: cpu plugin
249 * @tc.desc: Test whether the path exists.
250 * @tc.type: FUNC
251 */
252 HWTEST_F(CpuDataPluginTest, TestPath, TestSize.Level1)
253 {
254 g_path = GetFullPath(DEFAULT_TEST_PATH);
255 g_testPath = g_path;
256 EXPECT_NE("", g_path);
257 }
258
259 /**
260 * @tc.name: cpu plugin
261 * @tc.desc: Tid list test in a specific directory.
262 * @tc.type: FUNC
263 */
264 HWTEST_F(CpuDataPluginTest, TestTidlist, TestSize.Level1)
265 {
266 CpuDataPlugin cpuPlugin;
267 std::string path = g_path + "/proc/1872/task/";
268 DIR* dir = cpuPlugin.OpenDestDir(path);
269 EXPECT_NE(nullptr, dir);
270
271 std::vector<int> tidListTmp;
272 while (int32_t pid = cpuPlugin.GetValidTid(dir)) {
273 tidListTmp.push_back(pid);
274 sort(tidListTmp.begin(), tidListTmp.end());
275 }
276 EXPECT_TRUE(CheckTid(tidListTmp));
277 }
278
279 /**
280 * @tc.name: cpu plugin
281 * @tc.desc: a part of cpu information test for specific pid.
282 * @tc.type: FUNC
283 */
284 HWTEST_F(CpuDataPluginTest, TestPluginInfo, TestSize.Level1)
285 {
286 CpuDataPlugin cpuPlugin;
287 CpuData cpuData;
288 cpuPlugin.SetFreqPath(DEFAULT_TEST_PATH);
289 cpuPlugin.SetPath(DEFAULT_TEST_PATH + "/proc/");
290 EXPECT_TRUE(PluginCpuinfoStub(cpuPlugin, cpuData, 1872, true, false));
291
292 TestCpuUsage cpuUsage;
293 int64_t systemCpuTime = 0;
294 int64_t systemBootTime = 0;
295 int64_t Hz = cpuPlugin.GetUserHz();
296 int64_t processCpuTime = (g_pidStat.utime + g_pidStat.stime) * Hz;
297 GetSystemCpuTime(g_systemStat[0], Hz, systemCpuTime, systemBootTime);
298 GetCpuUsage(cpuUsage, Hz);
299
300 CpuUsageInfo cpuUsageInfo = cpuData.cpu_usage_info();
301 EXPECT_EQ(cpuUsageInfo.prev_process_cpu_time_ms(), 0);
302 EXPECT_EQ(cpuUsageInfo.prev_system_cpu_time_ms(), 0);
303 EXPECT_EQ(cpuUsageInfo.prev_system_boot_time_ms(), 0);
304 EXPECT_EQ(cpuUsageInfo.process_cpu_time_ms(), processCpuTime);
305 EXPECT_EQ(cpuUsageInfo.system_cpu_time_ms(), systemCpuTime);
306 EXPECT_EQ(cpuUsageInfo.system_boot_time_ms(), systemBootTime);
307 EXPECT_EQ(cpuData.process_num(), 1);
308 EXPECT_FLOAT_EQ(cpuData.user_load(), cpuUsage.userLoad);
309 EXPECT_FLOAT_EQ(cpuData.sys_load(), cpuUsage.sysLoad);
310 EXPECT_FLOAT_EQ(cpuData.total_load(), cpuUsage.totalLoad);
311 ASSERT_EQ(cpuUsageInfo.cores_size(), 6);
312 for (int i = 1; i <= CORE_NUM; i++) {
313 CpuCoreUsageInfo cpuCoreUsageInfo = cpuUsageInfo.cores()[i - 1];
314 GetSystemCpuTime(g_systemStat[i], Hz, systemCpuTime, systemBootTime);
315 EXPECT_EQ(cpuCoreUsageInfo.cpu_core(), g_systemStat[i].core);
316 EXPECT_EQ(cpuCoreUsageInfo.prev_system_cpu_time_ms(), 0);
317 EXPECT_EQ(cpuCoreUsageInfo.prev_system_boot_time_ms(), 0);
318 EXPECT_EQ(cpuCoreUsageInfo.system_cpu_time_ms(), systemCpuTime);
319 EXPECT_EQ(cpuCoreUsageInfo.system_boot_time_ms(), systemBootTime);
320
321 EXPECT_EQ(cpuCoreUsageInfo.frequency().min_frequency_khz(), g_freq[i - 1].minFreq);
322 EXPECT_EQ(cpuCoreUsageInfo.frequency().max_frequency_khz(), g_freq[i - 1].maxFreq);
323 EXPECT_EQ(cpuCoreUsageInfo.frequency().cur_frequency_khz(), g_freq[i - 1].curFreq);
324 if (i == 1) { // cpu0为大核
325 EXPECT_EQ(cpuCoreUsageInfo.is_little_core(), false);
326 } else {
327 EXPECT_EQ(cpuCoreUsageInfo.is_little_core(), true);
328 }
329 }
330 }
331
332 /**
333 * @tc.name: cpu plugin
334 * @tc.desc: cpu information test for specific pid.
335 * @tc.type: FUNC
336 */
337 HWTEST_F(CpuDataPluginTest, TestPlugin, TestSize.Level1)
338 {
339 CpuDataPlugin cpuPlugin;
340 CpuData cpuData;
341 g_path = g_testPath;
342 cpuPlugin.SetFreqPath(g_path);
343 g_path = g_testPath + "/proc/";
344 cpuPlugin.SetPath(g_path);
345 EXPECT_TRUE(PluginCpuinfoStub(cpuPlugin, cpuData, 1872, false, false));
346
347 int64_t Hz = cpuPlugin.GetUserHz();
348 int64_t threadCpuTime;
349 ASSERT_EQ(cpuData.thread_info_size(), 7);
350 for (int i = 0; i < THREAD_NUM && i < cpuData.thread_info().size(); i++) {
351 threadCpuTime = (g_tidStat[i].stat.utime + g_tidStat[i].stat.stime) * Hz;
352 ThreadInfo threadInfo = cpuData.thread_info()[i];
353 EXPECT_EQ(threadInfo.tid(), g_tidStat[i].tid);
354 EXPECT_STREQ(threadInfo.thread_name().c_str(), g_tidStat[i].name.c_str());
355 EXPECT_EQ(threadInfo.thread_state(), g_tidStat[i].state);
356 EXPECT_EQ(threadInfo.thread_cpu_time_ms(), threadCpuTime);
357 EXPECT_EQ(threadInfo.prev_thread_cpu_time_ms(), 0);
358 }
359
360 EXPECT_EQ(cpuPlugin.Stop(), 0);
361
362 // 缓冲区异常
363 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin, cpuData, 1872, false, true));
364 EXPECT_EQ(cpuPlugin.Stop(), 0);
365 }
366
367 /**
368 * @tc.name: cpu plugin
369 * @tc.desc: cpu plugin test for skip thread.
370 * @tc.type: FUNC
371 */
372 HWTEST_F(CpuDataPluginTest, TestSkipThread, TestSize.Level1)
373 {
374 CpuDataPlugin cpuPlugin;
375 CpuData cpuData;
376 g_path = g_testPath;
377 cpuPlugin.SetFreqPath(g_path);
378 g_path = g_testPath + "/proc/";
379 cpuPlugin.SetPath(g_path);
380 EXPECT_TRUE(PluginCpuinfoStub(cpuPlugin, cpuData, 1872, false, false, true));
381
382 ASSERT_EQ(cpuData.thread_info_size(), 0);
383 EXPECT_EQ(cpuPlugin.Stop(), 0);
384
385 // 缓冲区异常
386 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin, cpuData, 1872, false, true));
387 EXPECT_EQ(cpuPlugin.Stop(), 0);
388 }
389
390 /**
391 * @tc.name: cpu plugin
392 * @tc.desc: cpu information test for unusual path.
393 * @tc.type: FUNC
394 */
395 HWTEST_F(CpuDataPluginTest, TestPluginBoundary, TestSize.Level1)
396 {
397 CpuDataPlugin cpuPlugin;
398 CpuData cpuData;
399 g_path = g_testPath + "/proc/";
400 cpuPlugin.SetPath(g_path);
401 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin, cpuData, -1, false, false));
402 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin, cpuData, 12345, false, false));
403
404 CpuDataPlugin cpuPlugin2;
405 cpuPlugin2.SetPath("123");
406 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin2, cpuData, 1872, false, false));
407 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin2, cpuData, -1, false, false));
408 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin2, cpuData, 12345, false, false));
409 }
410
411 /**
412 * @tc.name: cpu plugin
413 * @tc.desc: cpu plugin registration test.
414 * @tc.type: FUNC
415 */
416 HWTEST_F(CpuDataPluginTest, TestPluginRegister, TestSize.Level1)
417 {
418 void* handle = dlopen(SO_PATH.c_str(), RTLD_LAZY);
419 ASSERT_NE(handle, nullptr);
420 PluginModuleStruct* cpuPlugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule");
421 ASSERT_NE(cpuPlugin, nullptr);
422 EXPECT_STREQ(cpuPlugin->name, "cpu-plugin");
423 EXPECT_EQ(cpuPlugin->resultBufferSizeHint, BUF_SIZE);
424
425 // Serialize config
426 CpuConfig protoConfig;
427 protoConfig.set_pid(TEST_PID);
428 int configLength = protoConfig.ByteSizeLong();
429 ASSERT_GT(configLength, 0);
430 std::vector<uint8_t> configBuffer(configLength);
431 EXPECT_TRUE(protoConfig.SerializeToArray(configBuffer.data(), configLength));
432
433 // run plugin
434 std::vector<uint8_t> dataBuffer(cpuPlugin->resultBufferSizeHint);
435 EXPECT_EQ(cpuPlugin->callbacks->onPluginSessionStart(configBuffer.data(), configLength), RET_SUCC);
436 ASSERT_GT(cpuPlugin->callbacks->onPluginReportResult(dataBuffer.data(), cpuPlugin->resultBufferSizeHint), 0);
437 EXPECT_EQ(cpuPlugin->callbacks->onPluginSessionStop(), RET_SUCC);
438
439 // 反序列化失败导致的start失败
440 EXPECT_EQ(cpuPlugin->callbacks->onPluginSessionStart(configBuffer.data(), configLength+1), RET_FAIL);
441 }
442
443 /**
444 * @tc.name: cpu plugin
445 * @tc.desc: a part of cpu process information test.
446 * @tc.type: FUNC
447 */
448 HWTEST_F(CpuDataPluginTest, TestPluginProcessInfo, TestSize.Level1)
449 {
450 CpuData cpuData;
451 CpuDataPlugin cpuPlugin;
452 int64_t Hz = cpuPlugin.GetUserHz();
453 std::string proStr1 = "2000 (ibus-x11) S 1 1865 1780 1025 1780 4194304 3233 0 457 0 50 10 40 10 20 0 7";
454 std::string proStr2 = "2000 (ibus-x12) R 1 1865 1780 1025 1780 4194304 3233 0 457 0 70 0 10 20 20 0 7";
455 int64_t processCpuTime1 = (g_pidStat1.utime + g_pidStat1.stime) * Hz;
456 int64_t processCpuTime2 = (g_pidStat2.utime + g_pidStat2.stime) * Hz;
457
458 // 存入proStr1
459 auto* cpuUsageInfo = cpuData.mutable_cpu_usage_info();
460 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr1.c_str(), proStr1.length());
461 CpuUsageInfo cpuUsageInfo1 = cpuData.cpu_usage_info();
462 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), 0);
463 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), processCpuTime1);
464
465 // 存入proStr2
466 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
467 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr2.c_str(), proStr2.length());
468 CpuUsageInfo cpuUsageInfo2 = cpuData.cpu_usage_info();
469 EXPECT_EQ(cpuUsageInfo2.prev_process_cpu_time_ms(), processCpuTime1);
470 EXPECT_EQ(cpuUsageInfo2.process_cpu_time_ms(), processCpuTime2);
471
472 // 重复存入proStr2
473 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
474 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr2.c_str(), proStr2.length());
475 CpuUsageInfo cpuUsageInfo3 = cpuData.cpu_usage_info();
476 EXPECT_EQ(cpuUsageInfo3.prev_process_cpu_time_ms(), processCpuTime2);
477 EXPECT_EQ(cpuUsageInfo3.process_cpu_time_ms(), processCpuTime2);
478 }
479
480 /**
481 * @tc.name: cpu plugin
482 * @tc.desc: cpu process information test for abnormal parameters.
483 * @tc.type: FUNC
484 */
485 HWTEST_F(CpuDataPluginTest, TestPluginProcessBoundary, TestSize.Level1)
486 {
487 CpuData cpuData;
488 CpuDataPlugin cpuPlugin;
489 std::string proStr;
490 int64_t Hz = cpuPlugin.GetUserHz();
491 int64_t processCpuTime = (g_pidStat1.utime + g_pidStat1.stime) * Hz;
492
493 // 空字符串
494 proStr = "";
495 auto* cpuUsageInfo = cpuData.mutable_cpu_usage_info();
496 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr.c_str(), proStr.length());
497 CpuUsageInfo cpuUsageInfo1 = cpuData.cpu_usage_info();
498 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), 0);
499 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), 0);
500
501 // 空格字符串
502 proStr = " ";
503 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
504 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr.c_str(), proStr.length());
505 cpuUsageInfo1 = cpuData.cpu_usage_info();
506 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), 0);
507 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), 0);
508
509 // 数据错误
510 proStr = "2000";
511 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
512 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr.c_str(), proStr.length());
513 cpuUsageInfo1 = cpuData.cpu_usage_info();
514 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), 0);
515 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), 0);
516
517 // 数据不够("2000 (ibus-x11) S 1 1865 1780 1025 1780 4194304 3233 0 457 0 50 10 40 10 20 0 7"需要的字符串是50 10 40 10)
518 proStr = "2000 (ibus-x11) S 1 1865 1780 1025 1780 4194304 3233 0 457 0 50 10";
519 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
520 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr.c_str(), proStr.length());
521 cpuUsageInfo1 = cpuData.cpu_usage_info();
522 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), 0);
523 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), 0);
524
525 // 多个空格,可以取出正确数据
526 proStr = "2000 (ibus-x11) S 1 1865 1780 1025 1780 4194304 3233 0 457 0 50 10 40 10 20 ";
527 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
528 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr.c_str(), proStr.length());
529 cpuUsageInfo1 = cpuData.cpu_usage_info();
530 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), 0);
531 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), processCpuTime);
532
533 // 最后一个数据之后没有空格,可以取出正确数据
534 proStr = "2000 (ibus-x11) S 1 1865 1780 1025 1780 4194304 3233 0 457 0 50 10 40 10 20";
535 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
536 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr.c_str(), proStr.length());
537 cpuUsageInfo1 = cpuData.cpu_usage_info();
538 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), processCpuTime);
539 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), processCpuTime);
540 }
541
542 /**
543 * @tc.name: cpu plugin
544 * @tc.desc: a part of cpu system information test.
545 * @tc.type: FUNC
546 */
547 HWTEST_F(CpuDataPluginTest, TestPluginSystemInfo, TestSize.Level1)
548 {
549 std::string sysStr1 = "cpu 1234567 2345678 1111111 1193291234 3546789 0 2345678 0 0\n"
550 "cpu0 2345678 662862 1966195 1111111 3571925 0 817371 0 0\n"
551 "cpu1 3861506 2345678 1702753 199535158 1752008 0 401639 0 0\n"
552 "cpu2 3549890 1111111 2345678 1234567 1133743 0 205972 0 0\n"
553 "cpu3 3336646 676939 1458898 2345678 854578 0 2345678 0 0\n"
554 "cpu4 1111111 601107 2305309 3546789 929594 0 1007959 0 0\n"
555 "cpu5 3546789 658673 1234567 197791346 738811 0 49496 0 0\n";
556 std::string sysStr2 = "cpu 3546789 2345678 1111111 1193291234 3546789 0 2345678 0 0\n"
557 "cpu0 3546789 662862 1966195 2345678 3571925 0 817371 0 0\n"
558 "cpu1 3861506 1111111 1702753 199535158 1752008 0 401639 0 0\n"
559 "cpu2 3549890 2345678 2345678 3546789 1111111 0 205972 0 0\n"
560 "cpu3 3336646 676939 1458898 2345678 854578 0 2345678 0 0\n"
561 "cpu4 2345678 601107 2305309 3546789 929594 0 1111111 0 0\n"
562 "cpu5 3546789 658673 3546789 197791346 738811 0 49496 0 0\n";
563 CpuData cpuData;
564 CpuDataPlugin cpuPlugin;
565 int64_t Hz = cpuPlugin.GetUserHz();
566
567 // 存入sysStr1
568 int64_t systemCpuTime1 = 0;
569 int64_t systemBootTime1 = 0;
570 CpuLoadData cpuLoadData;
571 GetSystemCpuTime(g_systemStat1[0], Hz, systemCpuTime1, systemBootTime1);
572 cpuPlugin.WriteSystemCpuUsage(*cpuData.mutable_cpu_usage_info(), cpuLoadData, sysStr1.c_str(), sysStr1.length());
573 CpuUsageInfo cpuUsageInfo1 = cpuData.cpu_usage_info();
574 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
575 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
576 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), systemCpuTime1);
577 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), systemBootTime1);
578 ASSERT_EQ(cpuUsageInfo1.cores_size(), CORE_NUM);
579 std::vector<int64_t> systemCpuTimeVec1(CORE_NUM);
580 std::vector<int64_t> systemBootTimeVec1(CORE_NUM);
581 for (int i = 1; i <= CORE_NUM; i++) {
582 CpuCoreUsageInfo cpuCoreUsageInfo1 = cpuUsageInfo1.cores()[i - 1];
583 GetSystemCpuTime(g_systemStat1[i], Hz, systemCpuTimeVec1[i-1], systemBootTimeVec1[i-1]);
584 EXPECT_EQ(cpuCoreUsageInfo1.cpu_core(), i-1);
585 EXPECT_EQ(cpuCoreUsageInfo1.prev_system_cpu_time_ms(), 0);
586 EXPECT_EQ(cpuCoreUsageInfo1.prev_system_boot_time_ms(), 0);
587 EXPECT_EQ(cpuCoreUsageInfo1.system_cpu_time_ms(), systemCpuTimeVec1[i-1]);
588 EXPECT_EQ(cpuCoreUsageInfo1.system_boot_time_ms(), systemBootTimeVec1[i-1]);
589 }
590
591 // 存入sysStr2
592 int64_t systemCpuTime2 = 0;
593 int64_t systemBootTime2 = 0;
594 GetSystemCpuTime(g_systemStat2[0], Hz, systemCpuTime2, systemBootTime2);
595 cpuPlugin.WriteSystemCpuUsage(*cpuData.mutable_cpu_usage_info(), cpuLoadData, sysStr2.c_str(), sysStr2.length());
596 CpuUsageInfo cpuUsageInfo2 = cpuData.cpu_usage_info();
597 EXPECT_EQ(cpuUsageInfo2.prev_system_cpu_time_ms(), systemCpuTime1);
598 EXPECT_EQ(cpuUsageInfo2.prev_system_boot_time_ms(), systemBootTime1);
599 EXPECT_EQ(cpuUsageInfo2.system_cpu_time_ms(), systemCpuTime2);
600 EXPECT_EQ(cpuUsageInfo2.system_boot_time_ms(), systemBootTime2);
601 ASSERT_EQ(cpuUsageInfo2.cores_size(), CORE_NUM*2);
602 std::vector<int64_t> systemCpuTimeVec2(CORE_NUM);
603 std::vector<int64_t> systemBootTimeVec2(CORE_NUM);
604 for (int i = 1; i <= CORE_NUM; i++) {
605 CpuCoreUsageInfo cpuCoreUsageInfo2 = cpuUsageInfo2.cores()[CORE_NUM+i-1];
606 GetSystemCpuTime(g_systemStat2[i], Hz, systemCpuTimeVec2[i-1], systemBootTimeVec2[i-1]);
607 EXPECT_EQ(cpuCoreUsageInfo2.cpu_core(), i-1);
608 EXPECT_EQ(cpuCoreUsageInfo2.prev_system_cpu_time_ms(), systemCpuTimeVec1[i-1]);
609 EXPECT_EQ(cpuCoreUsageInfo2.prev_system_boot_time_ms(), systemBootTimeVec1[i-1]);
610 EXPECT_EQ(cpuCoreUsageInfo2.system_cpu_time_ms(), systemCpuTimeVec2[i-1]);
611 EXPECT_EQ(cpuCoreUsageInfo2.system_boot_time_ms(), systemBootTimeVec2[i-1]);
612 }
613
614 // 重复存入sysStr2
615 cpuPlugin.WriteSystemCpuUsage(*cpuData.mutable_cpu_usage_info(), cpuLoadData, sysStr2.c_str(), sysStr2.length());
616 CpuUsageInfo cpuUsageInfo3 = cpuData.cpu_usage_info();
617 EXPECT_EQ(cpuUsageInfo3.prev_system_cpu_time_ms(), systemCpuTime2);
618 EXPECT_EQ(cpuUsageInfo3.prev_system_boot_time_ms(), systemBootTime2);
619 EXPECT_EQ(cpuUsageInfo3.system_cpu_time_ms(), systemCpuTime2);
620 EXPECT_EQ(cpuUsageInfo3.system_boot_time_ms(), systemBootTime2);
621 ASSERT_EQ(cpuUsageInfo3.cores_size(), CORE_NUM*3);
622 std::vector<int64_t> systemCpuTimeVec3(CORE_NUM);
623 std::vector<int64_t> systemBootTimeVec3(CORE_NUM);
624 for (int i = 1; i <= CORE_NUM; i++) {
625 CpuCoreUsageInfo cpuCoreUsageInfo3 = cpuUsageInfo3.cores()[CORE_NUM*2+i-1];
626 GetSystemCpuTime(g_systemStat2[i], Hz, systemCpuTimeVec3[i-1], systemBootTimeVec3[i-1]);
627 EXPECT_EQ(cpuCoreUsageInfo3.cpu_core(), i-1);
628 EXPECT_EQ(cpuCoreUsageInfo3.prev_system_cpu_time_ms(), systemCpuTimeVec2[i-1]);
629 EXPECT_EQ(cpuCoreUsageInfo3.prev_system_boot_time_ms(), systemBootTimeVec2[i-1]);
630 EXPECT_EQ(cpuCoreUsageInfo3.system_cpu_time_ms(), systemCpuTimeVec3[i-1]);
631 EXPECT_EQ(cpuCoreUsageInfo3.system_boot_time_ms(), systemBootTimeVec3[i-1]);
632 }
633 }
634
635 /**
636 * @tc.name: cpu plugin
637 * @tc.desc: cpu system information test for abnormal parameters.
638 * @tc.type: FUNC
639 */
640 HWTEST_F(CpuDataPluginTest, TestPluginSystemBoundary, TestSize.Level1)
641 {
642 CpuData cpuData;
643 CpuDataPlugin cpuPlugin;
644 std::string sysStr;
645 int64_t Hz = cpuPlugin.GetUserHz();
646 int64_t systemCpuTime = 0;
647 int64_t systemBootTime = 0;
648 GetSystemCpuTime(g_systemStat1[0], Hz, systemCpuTime, systemBootTime);
649 // 空字符串
650 sysStr = "";
651 CpuLoadData cpuLoadData;
652 cpuPlugin.WriteSystemCpuUsage(*cpuData.mutable_cpu_usage_info(), cpuLoadData, sysStr.c_str(), sysStr.length());
653 CpuUsageInfo cpuUsageInfo1 = cpuData.cpu_usage_info();
654 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
655 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
656 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), 0);
657 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), 0);
658 ASSERT_EQ(cpuUsageInfo1.cores_size(), 0);
659
660 // 空格字符串
661 sysStr = " ";
662 cpuPlugin.WriteSystemCpuUsage(*cpuData.mutable_cpu_usage_info(), cpuLoadData, sysStr.c_str(), sysStr.length());
663 cpuUsageInfo1 = cpuData.cpu_usage_info();
664 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
665 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
666 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), 0);
667 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), 0);
668 ASSERT_EQ(cpuUsageInfo1.cores_size(), 0);
669
670 // 数据错误
671 sysStr = "1000";
672 cpuPlugin.WriteSystemCpuUsage(*cpuData.mutable_cpu_usage_info(), cpuLoadData, sysStr.c_str(), sysStr.length());
673 cpuUsageInfo1 = cpuData.cpu_usage_info();
674 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
675 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
676 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), 0);
677 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), 0);
678 ASSERT_EQ(cpuUsageInfo1.cores_size(), 0);
679
680 // 数据不够
681 sysStr = "cpu 1234567 2345678 1111111 1193291234 3546789\n"
682 "cpu0 2345678 662862 1966195 1111111 3571925\n"
683 "cpu1 3861506 2345678 1702753 199535158 1752008\n"
684 "cpu2 3549890 1111111 2345678 1234567 1133743\n"
685 "cpu3 3336646 676939 1458898 2345678 854578\n"
686 "cpu4 1111111 601107 2305309 3546789 929594\n"
687 "cpu5 3546789 658673 1234567 197791346 738811\n";
688 cpuPlugin.WriteSystemCpuUsage(*cpuData.mutable_cpu_usage_info(), cpuLoadData, sysStr.c_str(), sysStr.length());
689 cpuUsageInfo1 = cpuData.cpu_usage_info();
690 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
691 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
692 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), 0);
693 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), 0);
694 ASSERT_EQ(cpuUsageInfo1.cores_size(), 0);
695
696 // 多个空格,可以取出正确数据
697 sysStr = "cpu 1234567 2345678 1111111 1193291234 3546789 0 2345678 0 0\n"
698 "cpu0 2345678 662862 1966195 1111111 3571925 0 817371 0 0\n"
699 "cpu1 3861506 2345678 1702753 199535158 1752008 0 401639 0 0\n"
700 "cpu2 3549890 1111111 2345678 1234567 1133743 0 205972 0 0\n"
701 "cpu3 3336646 676939 1458898 2345678 854578 0 2345678 0 0\n"
702 "cpu4 1111111 601107 2305309 3546789 929594 0 1007959 0 0\n"
703 "cpu5 3546789 658673 1234567 197791346 738811 0 49496 0 0\n";
704 cpuPlugin.WriteSystemCpuUsage(*cpuData.mutable_cpu_usage_info(), cpuLoadData, sysStr.c_str(), sysStr.length());
705 cpuUsageInfo1 = cpuData.cpu_usage_info();
706 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
707 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
708 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), systemCpuTime);
709 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), systemBootTime);
710 ASSERT_EQ(cpuUsageInfo1.cores_size(), CORE_NUM);
711 std::vector<int64_t> systemCpuTimeVec1(CORE_NUM);
712 std::vector<int64_t> systemBootTimeVec1(CORE_NUM);
713 for (int i = 1; i <= CORE_NUM; i++) {
714 CpuCoreUsageInfo cpuCoreUsageInfo = cpuUsageInfo1.cores()[i - 1];
715 GetSystemCpuTime(g_systemStat1[i], Hz, systemCpuTimeVec1[i-1], systemBootTimeVec1[i-1]);
716 EXPECT_EQ(cpuCoreUsageInfo.cpu_core(), i-1);
717 EXPECT_EQ(cpuCoreUsageInfo.prev_system_cpu_time_ms(), 0);
718 EXPECT_EQ(cpuCoreUsageInfo.prev_system_boot_time_ms(), 0);
719 EXPECT_EQ(cpuCoreUsageInfo.system_cpu_time_ms(), systemCpuTimeVec1[i-1]);
720 EXPECT_EQ(cpuCoreUsageInfo.system_boot_time_ms(), systemBootTimeVec1[i-1]);
721 }
722
723 // 最后一个数据之后没有空格,可以取出正确数据
724 sysStr = "cpu 1234567 2345678 1111111 1193291234 3546789 0 2345678 0 0\n"
725 "cpu0 2345678 662862 1966195 1111111 3571925 0 817371 0 0\n"
726 "cpu1 3861506 2345678 1702753 199535158 1752008 0 401639 0 0\n"
727 "cpu2 3549890 1111111 2345678 1234567 1133743 0 205972 0 0\n"
728 "cpu3 3336646 676939 1458898 2345678 854578 0 2345678 0 0\n"
729 "cpu4 1111111 601107 2305309 3546789 929594 0 1007959 0 0\n"
730 "cpu5 3546789 658673 1234567 197791346 738811 0 49496 0 0\n";
731 cpuPlugin.WriteSystemCpuUsage(*cpuData.mutable_cpu_usage_info(), cpuLoadData, sysStr.c_str(), sysStr.length());
732 cpuUsageInfo1 = cpuData.cpu_usage_info();
733 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), systemCpuTime);
734 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), systemBootTime);
735 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), systemCpuTime);
736 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), systemBootTime);
737 ASSERT_EQ(cpuUsageInfo1.cores_size(), CORE_NUM*2);
738 std::vector<int64_t> systemCpuTimeVec2(CORE_NUM);
739 std::vector<int64_t> systemBootTimeVec2(CORE_NUM);
740 for (int i = 1; i <= CORE_NUM; i++) {
741 CpuCoreUsageInfo cpuCoreUsageInfo = cpuUsageInfo1.cores()[CORE_NUM+i-1];
742 GetSystemCpuTime(g_systemStat1[i], Hz, systemCpuTimeVec2[i-1], systemBootTimeVec2[i-1]);
743 EXPECT_EQ(cpuCoreUsageInfo.cpu_core(), i-1);
744 EXPECT_EQ(cpuCoreUsageInfo.prev_system_cpu_time_ms(), systemCpuTimeVec1[i-1]);
745 EXPECT_EQ(cpuCoreUsageInfo.prev_system_boot_time_ms(), systemBootTimeVec1[i-1]);
746 EXPECT_EQ(cpuCoreUsageInfo.system_cpu_time_ms(), systemCpuTimeVec2[i-1]);
747 EXPECT_EQ(cpuCoreUsageInfo.system_boot_time_ms(), systemBootTimeVec2[i-1]);
748 }
749 }
750
751 /**
752 * @tc.name: cpu plugin
753 * @tc.desc: a part of cpu thread information test.
754 * @tc.type: FUNC
755 */
756 HWTEST_F(CpuDataPluginTest, TestPluginThreadInfo, TestSize.Level1)
757 {
758 std::vector<std::string> threadVec1;
759 threadVec1.push_back("1209 (skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8 0 0 20 0 19 0");
760 threadVec1.push_back("1646 (Jit thread pool) L 1746 1746 0 0 -1 1077936192 1831 0 0 0 2 1 0 0 20 0 19 0");
761 threadVec1.push_back("1654 (Signal Catcher) T 1746 1746 0 0 -1 1077936192 588 0 0 0 1 0 0 0 20 0 19 0");
762 threadVec1.push_back("1655 (HeapTaskDaemon) S 1746 1746 0 0 -1 1077936192 1515 0 0 0 3 0 0 0 24 4 19 0");
763 threadVec1.push_back("1656 (ReferenceQueueD) D 1746 1746 0 0 -1 1077936192 24 0 0 0 0 0 0 0 24 4 19 0");
764
765 std::vector<std::string> threadVec2;
766 threadVec2.push_back("1662 (FinalizerDaemon) T 1746 1746 0 0 -1 1077936192 18 0 0 0 0 0 0 0 24 4 19 0");
767 threadVec2.push_back("1663 (FinalizerWatchd) R 1746 1746 0 0 -1 1077936192 5 0 0 0 0 0 0 0 24 4 19 0");
768 threadVec2.push_back("1666 (Binder:1209_1) R 1746 1746 0 0 -1 1077936192 412 0 0 0 0 0 0 0 20 0 19 0");
769 threadVec2.push_back("1679 (Binder:1209_2) O 1746 1746 0 0 -1 1077936192 14 0 0 0 0 0 0 0 20 0 19 0");
770 threadVec2.push_back("1680 (Binder:1209_3) D 1746 1746 0 0 -1 1077936192 11513 0 4 0 54 8 0 0 20 0 49 0");
771 threadVec2.push_back("1681 (Binder:1209_4) S 1751 1751 0 0 -1 1077936192 17 0 0 0 0 0 0 0 20 0 24 0");
772 CpuData cpuData;
773 CpuDataPlugin cpuPlugin;
774 int64_t Hz = cpuPlugin.GetUserHz();
775
776 // 存入threadVec0-4
777 int32_t tid;
778 for (int i = 0; i < FIRST_THREAD_NUM; i++) {
779 auto* threadInfo = cpuData.add_thread_info();
780 tid = atoi(threadVec1[i].substr(0, threadVec1[i].find(" ")).c_str());
781 cpuPlugin.WriteThread(*threadInfo, threadVec1[i].c_str(), threadVec1[i].length(), tid);
782 }
783 ASSERT_EQ(cpuData.thread_info_size(), FIRST_THREAD_NUM);
784 int64_t threadCpuTime1;
785 for (int i = 0; i < FIRST_THREAD_NUM; i++) {
786 threadCpuTime1 = (g_tidStat1[i].stat.utime + g_tidStat1[i].stat.stime) * Hz;
787 ThreadInfo threadInfo1 = cpuData.thread_info()[i];
788 EXPECT_EQ(threadInfo1.tid(), g_tidStat1[i].tid);
789 EXPECT_STREQ(threadInfo1.thread_name().c_str(), g_tidStat1[i].name.c_str());
790 EXPECT_EQ(threadInfo1.thread_state(), g_tidStat1[i].state);
791 EXPECT_EQ(threadInfo1.prev_thread_cpu_time_ms(), 0);
792 EXPECT_EQ(threadInfo1.thread_cpu_time_ms(), threadCpuTime1);
793 }
794
795 // 存入threadVec5-10
796 for (int i = 0; i < SECOND_THREAD_NUM; i++) {
797 auto* threadInfo = cpuData.add_thread_info();
798 tid = atoi(threadVec2[i].substr(0, threadVec2[i].find(" ")).c_str());
799 cpuPlugin.WriteThread(*threadInfo, threadVec2[i].c_str(), threadVec2[i].length(), tid);
800 }
801 ASSERT_EQ(cpuData.thread_info_size(), FIRST_THREAD_NUM+SECOND_THREAD_NUM);
802 std::vector<int64_t> threadCpuTime2;
803 for (int i = 0; i < SECOND_THREAD_NUM; i++) {
804 threadCpuTime2.push_back((g_tidStat2[i].stat.utime + g_tidStat2[i].stat.stime) * Hz);
805 ThreadInfo threadInfo2 = cpuData.thread_info()[i+FIRST_THREAD_NUM];
806 EXPECT_EQ(threadInfo2.tid(), g_tidStat2[i].tid);
807 EXPECT_STREQ(threadInfo2.thread_name().c_str(), g_tidStat2[i].name.c_str());
808 EXPECT_EQ(threadInfo2.thread_state(), g_tidStat2[i].state);
809 EXPECT_EQ(threadInfo2.prev_thread_cpu_time_ms(), 0);
810 EXPECT_EQ(threadInfo2.thread_cpu_time_ms(), threadCpuTime2[i]);
811 }
812
813 // 重复存入threadVec5-10
814 for (int i = 0; i < SECOND_THREAD_NUM; i++) {
815 auto* threadInfo = cpuData.add_thread_info();
816 tid = atoi(threadVec2[i].substr(0, threadVec2[i].find(" ")).c_str());
817 cpuPlugin.WriteThread(*threadInfo, threadVec2[i].c_str(), threadVec2[i].length(), tid);
818 }
819
820 ASSERT_EQ(cpuData.thread_info_size(), FIRST_THREAD_NUM+SECOND_THREAD_NUM*2);
821 int64_t threadCpuTime3;
822 for (int i = 0; i < SECOND_THREAD_NUM; i++) {
823 threadCpuTime3 = (g_tidStat2[i].stat.utime + g_tidStat2[i].stat.stime) * Hz;
824 ThreadInfo threadInfo3 = cpuData.thread_info()[i+FIRST_THREAD_NUM+SECOND_THREAD_NUM];
825 EXPECT_EQ(threadInfo3.tid(), g_tidStat2[i].tid);
826 EXPECT_STREQ(threadInfo3.thread_name().c_str(), g_tidStat2[i].name.c_str());
827 EXPECT_EQ(threadInfo3.thread_state(), g_tidStat2[i].state);
828 EXPECT_EQ(threadInfo3.prev_thread_cpu_time_ms(), threadCpuTime2[i]);
829 EXPECT_EQ(threadInfo3.thread_cpu_time_ms(), threadCpuTime3);
830 }
831 }
832
833 /**
834 * @tc.name: cpu plugin
835 * @tc.desc: cpu thread information test for abnormal parameters.
836 * @tc.type: FUNC
837 */
838 HWTEST_F(CpuDataPluginTest, TestPluginThreadBoundary, TestSize.Level1)
839 {
840 CpuData cpuData;
841 CpuDataPlugin cpuPlugin;
842 std::string threadStr;
843 int thread_info_count = 0;
844 int64_t Hz = cpuPlugin.GetUserHz();
845 int64_t threadCpuTime = (g_tidStat1[0].stat.utime + g_tidStat1[0].stat.stime) * Hz;
846
847 // 空字符串
848 threadStr = "";
849 auto* threadInfo = cpuData.add_thread_info();
850 thread_info_count++;
851 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), 0);
852 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
853
854 // 空格字符串
855 threadStr = " ";
856 threadInfo = cpuData.add_thread_info();
857 thread_info_count++;
858 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), 0);
859 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
860
861 // 数据错误
862 threadStr = "1000";
863 threadInfo = cpuData.add_thread_info();
864 thread_info_count++;
865 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), 0);
866 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
867
868 // 数据不够
869 threadStr = "1209 (skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8";
870 threadInfo = cpuData.add_thread_info();
871 thread_info_count++;
872 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), 0);
873 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
874
875 // 线程名缺失左括号
876 threadStr = "1209 skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8 0 0 20 0 19 0";
877 int32_t tid = atoi(threadStr.substr(0, threadStr.find(" ")).c_str());
878 threadInfo = cpuData.add_thread_info();
879 thread_info_count++;
880 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), tid);
881 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
882 ThreadInfo threadInfo1 = cpuData.thread_info()[thread_info_count-1];
883 EXPECT_EQ(threadInfo1.tid(), g_tidStat1[0].tid);
884 EXPECT_STRNE(threadInfo1.thread_name().c_str(), g_tidStat1[0].name.c_str());
885 EXPECT_EQ(threadInfo1.thread_state(), g_tidStat1[0].state);
886 EXPECT_EQ(threadInfo1.prev_thread_cpu_time_ms(), 0);
887 EXPECT_EQ(threadInfo1.thread_cpu_time_ms(), threadCpuTime);
888
889 // 多个空格,可以取出正确数据
890 threadStr = "1209 (skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8 0 0 20 0 19 0";
891 tid = atoi(threadStr.substr(0, threadStr.find(" ")).c_str());
892 threadInfo = cpuData.add_thread_info();
893 thread_info_count++;
894 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), tid);
895 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
896 threadInfo1 = cpuData.thread_info()[thread_info_count-1];
897 EXPECT_EQ(threadInfo1.tid(), g_tidStat1[0].tid);
898 EXPECT_STREQ(threadInfo1.thread_name().c_str(), g_tidStat1[0].name.c_str());
899 EXPECT_EQ(threadInfo1.thread_state(), g_tidStat1[0].state);
900 EXPECT_EQ(threadInfo1.prev_thread_cpu_time_ms(), threadCpuTime);
901 EXPECT_EQ(threadInfo1.thread_cpu_time_ms(), threadCpuTime);
902
903 // 最后一个数据之后没有空格,可以取出正确数据
904 threadStr = "1209 (skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8 0 0 20";
905 tid = atoi(threadStr.substr(0, threadStr.find(" ")).c_str());
906 threadInfo = cpuData.add_thread_info();
907 thread_info_count++;
908 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), tid);
909 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
910 threadInfo1 = cpuData.thread_info()[thread_info_count-1];
911 EXPECT_EQ(threadInfo1.tid(), g_tidStat1[0].tid);
912 EXPECT_STREQ(threadInfo1.thread_name().c_str(), g_tidStat1[0].name.c_str());
913 EXPECT_EQ(threadInfo1.thread_state(), g_tidStat1[0].state);
914 EXPECT_EQ(threadInfo1.prev_thread_cpu_time_ms(), threadCpuTime);
915 EXPECT_EQ(threadInfo1.thread_cpu_time_ms(), threadCpuTime);
916 }
917
ExecuteBin(const std::string & bin,const std::vector<std::string> & args)918 bool ExecuteBin(const std::string& bin, const std::vector<std::string>& args)
919 {
920 std::vector<char*> argv;
921 for (size_t i = 0; i < args.size(); i++) {
922 argv.push_back(const_cast<char*>(args[i].c_str()));
923 }
924 argv.push_back(nullptr); // last item in argv must be NULL
925
926 int retval = execvp(bin.c_str(), argv.data());
927 CHECK_TRUE(retval != -1, false, "execv %s failed, %d!", bin.c_str(), errno);
928 _exit(EXIT_FAILURE);
929 abort(); // never should be here.
930 return true;
931 }
932
933 /**
934 * @tc.name: cpu plugin
935 * @tc.desc: test ParseCpuInfo for pid
936 * @tc.type: FUNC
937 */
938 HWTEST_F(CpuDataPluginTest, TestPid, TestSize.Level1)
939 {
940 CpuDataPlugin plugin1, plugin2;
941 CpuData cpuData1, cpuData2;
942
943 std::string cmd = "chmod 777 " + DEFAULT_BIN_PATH;
944 system(cmd.c_str());
945
946 pid_t pid1 = fork();
947 if (pid1 == 0) {
948 // set 0, not to do
949 std::vector<std::string> argv = {"childpidtest1", "0"};
950 ASSERT_TRUE(ExecuteBin(DEFAULT_BIN_PATH, argv));
951 }
952 pid_t pid2 = fork();
953 if (pid2 == 0) {
954 // set 1, consume cpu
955 std::vector<std::string> argv = {"childpidtest2", "1"};
956 ASSERT_TRUE(ExecuteBin(DEFAULT_BIN_PATH, argv));
957 }
958
959 #ifdef COVERAGE_TEST
960 const int coverageSleepTime = 5; // sleep 5s
961 sleep(coverageSleepTime);
962 #else
963 sleep(1); // 睡眠1s,确保pid1进入睡眠状态,pid2进入while循环
964 #endif // COVERAGE_TEST
965 EXPECT_TRUE(PluginCpuinfoStub(plugin1, cpuData1, static_cast<int>(pid1), false, false));
966 EXPECT_TRUE(PluginCpuinfoStub(plugin2, cpuData2, static_cast<int>(pid2), false, false));
967 #ifdef __aarch64__
968 EXPECT_LT(cpuData1.cpu_usage_info().process_cpu_time_ms(), cpuData2.cpu_usage_info().process_cpu_time_ms());
969 #endif
970
971 while (waitpid(-1, nullptr, WNOHANG) == 0) {
972 kill(pid1, SIGKILL);
973 kill(pid2, SIGKILL);
974 }
975
976 plugin1.Stop();
977 plugin2.Stop();
978 }
979 } // namespace
980