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