1 /*
2 * Copyright (c) 2021 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 <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 + g_pidStat.cutime + g_pidStat.cstime) * 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 +
355 g_tidStat[i].stat.cutime + g_tidStat[i].stat.cstime) * Hz;
356 ThreadInfo threadInfo = cpuData.thread_info()[i];
357 EXPECT_EQ(threadInfo.tid(), g_tidStat[i].tid);
358 EXPECT_STREQ(threadInfo.thread_name().c_str(), g_tidStat[i].name.c_str());
359 EXPECT_EQ(threadInfo.thread_state(), g_tidStat[i].state);
360 EXPECT_EQ(threadInfo.thread_cpu_time_ms(), threadCpuTime);
361 EXPECT_EQ(threadInfo.prev_thread_cpu_time_ms(), 0);
362 }
363
364 EXPECT_EQ(cpuPlugin.Stop(), 0);
365
366 // 缓冲区异常
367 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin, cpuData, 1872, false, true));
368 EXPECT_EQ(cpuPlugin.Stop(), 0);
369 }
370
371 /**
372 * @tc.name: cpu plugin
373 * @tc.desc: cpu information test for unusual path.
374 * @tc.type: FUNC
375 */
376 HWTEST_F(CpuDataPluginTest, TestPluginBoundary, TestSize.Level1)
377 {
378 CpuDataPlugin cpuPlugin;
379 CpuData cpuData;
380 g_path = g_testPath + "/proc/";
381 cpuPlugin.SetPath(g_path);
382 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin, cpuData, -1, false, false));
383 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin, cpuData, 12345, false, false));
384
385 CpuDataPlugin cpuPlugin2;
386 cpuPlugin2.SetPath("123");
387 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin2, cpuData, 1872, false, false));
388 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin2, cpuData, -1, false, false));
389 EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin2, cpuData, 12345, false, false));
390 }
391
392 /**
393 * @tc.name: cpu plugin
394 * @tc.desc: cpu plugin registration test.
395 * @tc.type: FUNC
396 */
397 HWTEST_F(CpuDataPluginTest, TestPluginRegister, TestSize.Level1)
398 {
399 void* handle = dlopen(SO_PATH.c_str(), RTLD_LAZY);
400 ASSERT_NE(handle, nullptr);
401 PluginModuleStruct* cpuPlugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule");
402 ASSERT_NE(cpuPlugin, nullptr);
403 EXPECT_STREQ(cpuPlugin->name, "cpu-plugin");
404 EXPECT_EQ(cpuPlugin->resultBufferSizeHint, BUF_SIZE);
405
406 // Serialize config
407 CpuConfig protoConfig;
408 protoConfig.set_pid(TEST_PID);
409 int configLength = protoConfig.ByteSizeLong();
410 ASSERT_GT(configLength, 0);
411 std::vector<uint8_t> configBuffer(configLength);
412 EXPECT_TRUE(protoConfig.SerializeToArray(configBuffer.data(), configLength));
413
414 // run plugin
415 std::vector<uint8_t> dataBuffer(cpuPlugin->resultBufferSizeHint);
416 EXPECT_EQ(cpuPlugin->callbacks->onPluginSessionStart(configBuffer.data(), configLength), RET_SUCC);
417 ASSERT_GT(cpuPlugin->callbacks->onPluginReportResult(dataBuffer.data(), cpuPlugin->resultBufferSizeHint), 0);
418 EXPECT_EQ(cpuPlugin->callbacks->onPluginSessionStop(), RET_SUCC);
419
420 // 反序列化失败导致的start失败
421 EXPECT_EQ(cpuPlugin->callbacks->onPluginSessionStart(configBuffer.data(), configLength+1), RET_FAIL);
422 }
423
424 /**
425 * @tc.name: cpu plugin
426 * @tc.desc: a part of cpu process information test.
427 * @tc.type: FUNC
428 */
429 HWTEST_F(CpuDataPluginTest, TestPluginProcessInfo, TestSize.Level1)
430 {
431 CpuData cpuData;
432 CpuDataPlugin cpuPlugin;
433 int64_t Hz = cpuPlugin.GetUserHz();
434 std::string proStr1 = "2000 (ibus-x11) S 1 1865 1780 1025 1780 4194304 3233 0 457 0 50 10 40 10 20 0 7";
435 std::string proStr2 = "2000 (ibus-x12) R 1 1865 1780 1025 1780 4194304 3233 0 457 0 70 0 10 20 20 0 7";
436 int64_t processCpuTime1 = (g_pidStat1.utime + g_pidStat1.stime + g_pidStat1.cutime + g_pidStat1.cstime) * Hz;
437 int64_t processCpuTime2 = (g_pidStat2.utime + g_pidStat2.stime + g_pidStat2.cutime + g_pidStat2.cstime) * Hz;
438
439 // 存入proStr1
440 auto* cpuUsageInfo = cpuData.mutable_cpu_usage_info();
441 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr1.c_str(), proStr1.length());
442 CpuUsageInfo cpuUsageInfo1 = cpuData.cpu_usage_info();
443 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), 0);
444 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), processCpuTime1);
445
446 // 存入proStr2
447 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
448 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr2.c_str(), proStr2.length());
449 CpuUsageInfo cpuUsageInfo2 = cpuData.cpu_usage_info();
450 EXPECT_EQ(cpuUsageInfo2.prev_process_cpu_time_ms(), processCpuTime1);
451 EXPECT_EQ(cpuUsageInfo2.process_cpu_time_ms(), processCpuTime2);
452
453 // 重复存入proStr2
454 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
455 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr2.c_str(), proStr2.length());
456 CpuUsageInfo cpuUsageInfo3 = cpuData.cpu_usage_info();
457 EXPECT_EQ(cpuUsageInfo3.prev_process_cpu_time_ms(), processCpuTime2);
458 EXPECT_EQ(cpuUsageInfo3.process_cpu_time_ms(), processCpuTime2);
459 }
460
461 /**
462 * @tc.name: cpu plugin
463 * @tc.desc: cpu process information test for abnormal parameters.
464 * @tc.type: FUNC
465 */
466 HWTEST_F(CpuDataPluginTest, TestPluginProcessBoundary, TestSize.Level1)
467 {
468 CpuData cpuData;
469 CpuDataPlugin cpuPlugin;
470 std::string proStr;
471 int64_t Hz = cpuPlugin.GetUserHz();
472 int64_t processCpuTime = (g_pidStat1.utime + g_pidStat1.stime + g_pidStat1.cutime + g_pidStat1.cstime) * Hz;
473
474 // 空字符串
475 proStr = "";
476 auto* cpuUsageInfo = cpuData.mutable_cpu_usage_info();
477 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr.c_str(), proStr.length());
478 CpuUsageInfo cpuUsageInfo1 = cpuData.cpu_usage_info();
479 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), 0);
480 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), 0);
481
482 // 空格字符串
483 proStr = " ";
484 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
485 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr.c_str(), proStr.length());
486 cpuUsageInfo1 = cpuData.cpu_usage_info();
487 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), 0);
488 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), 0);
489
490 // 数据错误
491 proStr = "2000";
492 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
493 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr.c_str(), proStr.length());
494 cpuUsageInfo1 = cpuData.cpu_usage_info();
495 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), 0);
496 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), 0);
497
498 // 数据不够("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)
499 proStr = "2000 (ibus-x11) S 1 1865 1780 1025 1780 4194304 3233 0 457 0 50 10";
500 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
501 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr.c_str(), proStr.length());
502 cpuUsageInfo1 = cpuData.cpu_usage_info();
503 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), 0);
504 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), 0);
505
506 // 多个空格,可以取出正确数据
507 proStr = "2000 (ibus-x11) S 1 1865 1780 1025 1780 4194304 3233 0 457 0 50 10 40 10 20 ";
508 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
509 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr.c_str(), proStr.length());
510 cpuUsageInfo1 = cpuData.cpu_usage_info();
511 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), 0);
512 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), processCpuTime);
513
514 // 最后一个数据之后没有空格,可以取出正确数据
515 proStr = "2000 (ibus-x11) S 1 1865 1780 1025 1780 4194304 3233 0 457 0 50 10 40 10 20";
516 cpuUsageInfo = cpuData.mutable_cpu_usage_info();
517 cpuPlugin.WriteProcessCpuUsage(*cpuUsageInfo, proStr.c_str(), proStr.length());
518 cpuUsageInfo1 = cpuData.cpu_usage_info();
519 EXPECT_EQ(cpuUsageInfo1.prev_process_cpu_time_ms(), processCpuTime);
520 EXPECT_EQ(cpuUsageInfo1.process_cpu_time_ms(), processCpuTime);
521 }
522
523 /**
524 * @tc.name: cpu plugin
525 * @tc.desc: a part of cpu system information test.
526 * @tc.type: FUNC
527 */
528 HWTEST_F(CpuDataPluginTest, TestPluginSystemInfo, TestSize.Level1)
529 {
530 std::string sysStr1 = "cpu 1234567 2345678 1111111 1193291234 3546789 0 2345678 0 0\n"
531 "cpu0 2345678 662862 1966195 1111111 3571925 0 817371 0 0\n"
532 "cpu1 3861506 2345678 1702753 199535158 1752008 0 401639 0 0\n"
533 "cpu2 3549890 1111111 2345678 1234567 1133743 0 205972 0 0\n"
534 "cpu3 3336646 676939 1458898 2345678 854578 0 2345678 0 0\n"
535 "cpu4 1111111 601107 2305309 3546789 929594 0 1007959 0 0\n"
536 "cpu5 3546789 658673 1234567 197791346 738811 0 49496 0 0\n";
537 std::string sysStr2 = "cpu 3546789 2345678 1111111 1193291234 3546789 0 2345678 0 0\n"
538 "cpu0 3546789 662862 1966195 2345678 3571925 0 817371 0 0\n"
539 "cpu1 3861506 1111111 1702753 199535158 1752008 0 401639 0 0\n"
540 "cpu2 3549890 2345678 2345678 3546789 1111111 0 205972 0 0\n"
541 "cpu3 3336646 676939 1458898 2345678 854578 0 2345678 0 0\n"
542 "cpu4 2345678 601107 2305309 3546789 929594 0 1111111 0 0\n"
543 "cpu5 3546789 658673 3546789 197791346 738811 0 49496 0 0\n";
544 CpuData cpuData;
545 CpuDataPlugin cpuPlugin;
546 int64_t Hz = cpuPlugin.GetUserHz();
547
548 // 存入sysStr1
549 int64_t systemCpuTime1 = 0;
550 int64_t systemBootTime1 = 0;
551 GetSystemCpuTime(g_systemStat1[0], Hz, systemCpuTime1, systemBootTime1);
552 cpuPlugin.WriteSystemCpuUsage(cpuData, 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, 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, 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 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr.c_str(), sysStr.length());
632 CpuUsageInfo cpuUsageInfo1 = cpuData.cpu_usage_info();
633 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
634 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
635 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), 0);
636 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), 0);
637 ASSERT_EQ(cpuUsageInfo1.cores_size(), 0);
638
639 // 空格字符串
640 sysStr = " ";
641 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr.c_str(), sysStr.length());
642 cpuUsageInfo1 = cpuData.cpu_usage_info();
643 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
644 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
645 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), 0);
646 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), 0);
647 ASSERT_EQ(cpuUsageInfo1.cores_size(), 0);
648
649 // 数据错误
650 sysStr = "1000";
651 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr.c_str(), sysStr.length());
652 cpuUsageInfo1 = cpuData.cpu_usage_info();
653 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
654 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
655 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), 0);
656 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), 0);
657 ASSERT_EQ(cpuUsageInfo1.cores_size(), 0);
658
659 // 数据不够
660 sysStr = "cpu 1234567 2345678 1111111 1193291234 3546789\n"
661 "cpu0 2345678 662862 1966195 1111111 3571925\n"
662 "cpu1 3861506 2345678 1702753 199535158 1752008\n"
663 "cpu2 3549890 1111111 2345678 1234567 1133743\n"
664 "cpu3 3336646 676939 1458898 2345678 854578\n"
665 "cpu4 1111111 601107 2305309 3546789 929594\n"
666 "cpu5 3546789 658673 1234567 197791346 738811\n";
667 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr.c_str(), sysStr.length());
668 cpuUsageInfo1 = cpuData.cpu_usage_info();
669 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
670 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
671 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), 0);
672 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), 0);
673 ASSERT_EQ(cpuUsageInfo1.cores_size(), 0);
674
675 // 多个空格,可以取出正确数据
676 sysStr = "cpu 1234567 2345678 1111111 1193291234 3546789 0 2345678 0 0\n"
677 "cpu0 2345678 662862 1966195 1111111 3571925 0 817371 0 0\n"
678 "cpu1 3861506 2345678 1702753 199535158 1752008 0 401639 0 0\n"
679 "cpu2 3549890 1111111 2345678 1234567 1133743 0 205972 0 0\n"
680 "cpu3 3336646 676939 1458898 2345678 854578 0 2345678 0 0\n"
681 "cpu4 1111111 601107 2305309 3546789 929594 0 1007959 0 0\n"
682 "cpu5 3546789 658673 1234567 197791346 738811 0 49496 0 0\n";
683 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr.c_str(), sysStr.length());
684 cpuUsageInfo1 = cpuData.cpu_usage_info();
685 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
686 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
687 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), systemCpuTime);
688 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), systemBootTime);
689 ASSERT_EQ(cpuUsageInfo1.cores_size(), CORE_NUM);
690 std::vector<int64_t> systemCpuTimeVec1(CORE_NUM);
691 std::vector<int64_t> systemBootTimeVec1(CORE_NUM);
692 for (int i = 1; i <= CORE_NUM; i++) {
693 CpuCoreUsageInfo cpuCoreUsageInfo = cpuUsageInfo1.cores()[i - 1];
694 GetSystemCpuTime(g_systemStat1[i], Hz, systemCpuTimeVec1[i-1], systemBootTimeVec1[i-1]);
695 EXPECT_EQ(cpuCoreUsageInfo.cpu_core(), i-1);
696 EXPECT_EQ(cpuCoreUsageInfo.prev_system_cpu_time_ms(), 0);
697 EXPECT_EQ(cpuCoreUsageInfo.prev_system_boot_time_ms(), 0);
698 EXPECT_EQ(cpuCoreUsageInfo.system_cpu_time_ms(), systemCpuTimeVec1[i-1]);
699 EXPECT_EQ(cpuCoreUsageInfo.system_boot_time_ms(), systemBootTimeVec1[i-1]);
700 }
701
702 // 最后一个数据之后没有空格,可以取出正确数据
703 sysStr = "cpu 1234567 2345678 1111111 1193291234 3546789 0 2345678 0 0\n"
704 "cpu0 2345678 662862 1966195 1111111 3571925 0 817371 0 0\n"
705 "cpu1 3861506 2345678 1702753 199535158 1752008 0 401639 0 0\n"
706 "cpu2 3549890 1111111 2345678 1234567 1133743 0 205972 0 0\n"
707 "cpu3 3336646 676939 1458898 2345678 854578 0 2345678 0 0\n"
708 "cpu4 1111111 601107 2305309 3546789 929594 0 1007959 0 0\n"
709 "cpu5 3546789 658673 1234567 197791346 738811 0 49496 0 0\n";
710 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr.c_str(), sysStr.length());
711 cpuUsageInfo1 = cpuData.cpu_usage_info();
712 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), systemCpuTime);
713 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), systemBootTime);
714 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), systemCpuTime);
715 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), systemBootTime);
716 ASSERT_EQ(cpuUsageInfo1.cores_size(), CORE_NUM*2);
717 std::vector<int64_t> systemCpuTimeVec2(CORE_NUM);
718 std::vector<int64_t> systemBootTimeVec2(CORE_NUM);
719 for (int i = 1; i <= CORE_NUM; i++) {
720 CpuCoreUsageInfo cpuCoreUsageInfo = cpuUsageInfo1.cores()[CORE_NUM+i-1];
721 GetSystemCpuTime(g_systemStat1[i], Hz, systemCpuTimeVec2[i-1], systemBootTimeVec2[i-1]);
722 EXPECT_EQ(cpuCoreUsageInfo.cpu_core(), i-1);
723 EXPECT_EQ(cpuCoreUsageInfo.prev_system_cpu_time_ms(), systemCpuTimeVec1[i-1]);
724 EXPECT_EQ(cpuCoreUsageInfo.prev_system_boot_time_ms(), systemBootTimeVec1[i-1]);
725 EXPECT_EQ(cpuCoreUsageInfo.system_cpu_time_ms(), systemCpuTimeVec2[i-1]);
726 EXPECT_EQ(cpuCoreUsageInfo.system_boot_time_ms(), systemBootTimeVec2[i-1]);
727 }
728 }
729
730 /**
731 * @tc.name: cpu plugin
732 * @tc.desc: a part of cpu thread information test.
733 * @tc.type: FUNC
734 */
735 HWTEST_F(CpuDataPluginTest, TestPluginThreadInfo, TestSize.Level1)
736 {
737 std::vector<std::string> threadVec1;
738 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");
739 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");
740 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");
741 threadVec1.push_back("1655 (HeapTaskDaemon) S 1746 1746 0 0 -1 1077936192 1515 0 0 0 3 0 0 0 24 4 19 0");
742 threadVec1.push_back("1656 (ReferenceQueueD) D 1746 1746 0 0 -1 1077936192 24 0 0 0 0 0 0 0 24 4 19 0");
743
744 std::vector<std::string> threadVec2;
745 threadVec2.push_back("1662 (FinalizerDaemon) T 1746 1746 0 0 -1 1077936192 18 0 0 0 0 0 0 0 24 4 19 0");
746 threadVec2.push_back("1663 (FinalizerWatchd) R 1746 1746 0 0 -1 1077936192 5 0 0 0 0 0 0 0 24 4 19 0");
747 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");
748 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");
749 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");
750 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");
751 CpuData cpuData;
752 CpuDataPlugin cpuPlugin;
753 int64_t Hz = cpuPlugin.GetUserHz();
754
755 // 存入threadVec0-4
756 int32_t tid;
757 for (int i = 0; i < FIRST_THREAD_NUM; i++) {
758 auto* threadInfo = cpuData.add_thread_info();
759 tid = atoi(threadVec1[i].substr(0, threadVec1[i].find(" ")).c_str());
760 cpuPlugin.WriteThread(*threadInfo, threadVec1[i].c_str(), threadVec1[i].length(), tid);
761 }
762 ASSERT_EQ(cpuData.thread_info_size(), FIRST_THREAD_NUM);
763 int64_t threadCpuTime1;
764 for (int i = 0; i < FIRST_THREAD_NUM; i++) {
765 threadCpuTime1 = (g_tidStat1[i].stat.utime + g_tidStat1[i].stat.stime +
766 g_tidStat1[i].stat.cutime + g_tidStat1[i].stat.cstime) * 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 +
785 g_tidStat2[i].stat.cutime + g_tidStat2[i].stat.cstime) * Hz);
786 ThreadInfo threadInfo2 = cpuData.thread_info()[i+FIRST_THREAD_NUM];
787 EXPECT_EQ(threadInfo2.tid(), g_tidStat2[i].tid);
788 EXPECT_STREQ(threadInfo2.thread_name().c_str(), g_tidStat2[i].name.c_str());
789 EXPECT_EQ(threadInfo2.thread_state(), g_tidStat2[i].state);
790 EXPECT_EQ(threadInfo2.prev_thread_cpu_time_ms(), 0);
791 EXPECT_EQ(threadInfo2.thread_cpu_time_ms(), threadCpuTime2[i]);
792 }
793
794 // 重复存入threadVec5-10
795 for (int i = 0; i < SECOND_THREAD_NUM; i++) {
796 auto* threadInfo = cpuData.add_thread_info();
797 tid = atoi(threadVec2[i].substr(0, threadVec2[i].find(" ")).c_str());
798 cpuPlugin.WriteThread(*threadInfo, threadVec2[i].c_str(), threadVec2[i].length(), tid);
799 }
800
801 ASSERT_EQ(cpuData.thread_info_size(), FIRST_THREAD_NUM+SECOND_THREAD_NUM*2);
802 int64_t threadCpuTime3;
803 for (int i = 0; i < SECOND_THREAD_NUM; i++) {
804 threadCpuTime3 = (g_tidStat2[i].stat.utime + g_tidStat2[i].stat.stime +
805 g_tidStat2[i].stat.cutime + g_tidStat2[i].stat.cstime) * Hz;
806 ThreadInfo threadInfo3 = cpuData.thread_info()[i+FIRST_THREAD_NUM+SECOND_THREAD_NUM];
807 EXPECT_EQ(threadInfo3.tid(), g_tidStat2[i].tid);
808 EXPECT_STREQ(threadInfo3.thread_name().c_str(), g_tidStat2[i].name.c_str());
809 EXPECT_EQ(threadInfo3.thread_state(), g_tidStat2[i].state);
810 EXPECT_EQ(threadInfo3.prev_thread_cpu_time_ms(), threadCpuTime2[i]);
811 EXPECT_EQ(threadInfo3.thread_cpu_time_ms(), threadCpuTime3);
812 }
813 }
814
815 /**
816 * @tc.name: cpu plugin
817 * @tc.desc: cpu thread information test for abnormal parameters.
818 * @tc.type: FUNC
819 */
820 HWTEST_F(CpuDataPluginTest, TestPluginThreadBoundary, TestSize.Level1)
821 {
822 CpuData cpuData;
823 CpuDataPlugin cpuPlugin;
824 std::string threadStr;
825 int thread_info_count = 0;
826 int64_t Hz = cpuPlugin.GetUserHz();
827 int64_t threadCpuTime = (g_tidStat1[0].stat.utime + g_tidStat1[0].stat.stime + g_tidStat1[0].stat.cutime
828 + g_tidStat1[0].stat.cstime) * Hz;
829
830 // 空字符串
831 threadStr = "";
832 auto* threadInfo = cpuData.add_thread_info();
833 thread_info_count++;
834 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), 0);
835 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
836
837 // 空格字符串
838 threadStr = " ";
839 threadInfo = cpuData.add_thread_info();
840 thread_info_count++;
841 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), 0);
842 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
843
844 // 数据错误
845 threadStr = "1000";
846 threadInfo = cpuData.add_thread_info();
847 thread_info_count++;
848 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), 0);
849 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
850
851 // 数据不够
852 threadStr = "1209 (skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8";
853 threadInfo = cpuData.add_thread_info();
854 thread_info_count++;
855 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), 0);
856 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
857
858 // 线程名缺失左括号
859 threadStr = "1209 skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8 0 0 20 0 19 0";
860 int32_t tid = atoi(threadStr.substr(0, threadStr.find(" ")).c_str());
861 threadInfo = cpuData.add_thread_info();
862 thread_info_count++;
863 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), tid);
864 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
865 ThreadInfo threadInfo1 = cpuData.thread_info()[thread_info_count-1];
866 EXPECT_EQ(threadInfo1.tid(), g_tidStat1[0].tid);
867 EXPECT_STRNE(threadInfo1.thread_name().c_str(), g_tidStat1[0].name.c_str());
868 EXPECT_EQ(threadInfo1.thread_state(), g_tidStat1[0].state);
869 EXPECT_EQ(threadInfo1.prev_thread_cpu_time_ms(), 0);
870 EXPECT_EQ(threadInfo1.thread_cpu_time_ms(), threadCpuTime);
871
872 // 多个空格,可以取出正确数据
873 threadStr = "1209 (skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8 0 0 20 0 19 0";
874 tid = atoi(threadStr.substr(0, threadStr.find(" ")).c_str());
875 threadInfo = cpuData.add_thread_info();
876 thread_info_count++;
877 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), tid);
878 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
879 threadInfo1 = cpuData.thread_info()[thread_info_count-1];
880 EXPECT_EQ(threadInfo1.tid(), g_tidStat1[0].tid);
881 EXPECT_STREQ(threadInfo1.thread_name().c_str(), g_tidStat1[0].name.c_str());
882 EXPECT_EQ(threadInfo1.thread_state(), g_tidStat1[0].state);
883 EXPECT_EQ(threadInfo1.prev_thread_cpu_time_ms(), threadCpuTime);
884 EXPECT_EQ(threadInfo1.thread_cpu_time_ms(), threadCpuTime);
885
886 // 最后一个数据之后没有空格,可以取出正确数据
887 threadStr = "1209 (skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8 0 0 20";
888 tid = atoi(threadStr.substr(0, threadStr.find(" ")).c_str());
889 threadInfo = cpuData.add_thread_info();
890 thread_info_count++;
891 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), tid);
892 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
893 threadInfo1 = cpuData.thread_info()[thread_info_count-1];
894 EXPECT_EQ(threadInfo1.tid(), g_tidStat1[0].tid);
895 EXPECT_STREQ(threadInfo1.thread_name().c_str(), g_tidStat1[0].name.c_str());
896 EXPECT_EQ(threadInfo1.thread_state(), g_tidStat1[0].state);
897 EXPECT_EQ(threadInfo1.prev_thread_cpu_time_ms(), threadCpuTime);
898 EXPECT_EQ(threadInfo1.thread_cpu_time_ms(), threadCpuTime);
899 }
900
ExecuteBin(const std::string & bin,const std::vector<std::string> & args)901 bool ExecuteBin(const std::string& bin, const std::vector<std::string>& args)
902 {
903 std::vector<char*> argv;
904 for (size_t i = 0; i < args.size(); i++) {
905 argv.push_back(const_cast<char*>(args[i].c_str()));
906 }
907 argv.push_back(nullptr); // last item in argv must be NULL
908
909 int retval = execvp(bin.c_str(), argv.data());
910 CHECK_TRUE(retval != -1, false, "execv %s failed, %d!", bin.c_str(), errno);
911 _exit(EXIT_FAILURE);
912 abort(); // never should be here.
913 return true;
914 }
915
916 /**
917 * @tc.name: cpu plugin
918 * @tc.desc: test ParseCpuInfo for pid
919 * @tc.type: FUNC
920 */
921 HWTEST_F(CpuDataPluginTest, TestPid, TestSize.Level1)
922 {
923 CpuDataPlugin plugin1, plugin2;
924 CpuData cpuData1, cpuData2;
925
926 std::string cmd = "chmod 777 " + DEFAULT_BIN_PATH;
927 system(cmd.c_str());
928
929 pid_t pid1 = fork();
930 if (pid1 == 0) {
931 // set 0, not to do
932 std::vector<std::string> argv = {"childpidtest1", "0"};
933 ASSERT_TRUE(ExecuteBin(DEFAULT_BIN_PATH, argv));
934 }
935 pid_t pid2 = fork();
936 if (pid2 == 0) {
937 // set 1, consume cpu
938 std::vector<std::string> argv = {"childpidtest2", "1"};
939 ASSERT_TRUE(ExecuteBin(DEFAULT_BIN_PATH, argv));
940 }
941
942 sleep(1); // 睡眠1s,确保pid1进入睡眠状态,pid2进入while循环
943 EXPECT_TRUE(PluginCpuinfoStub(plugin1, cpuData1, static_cast<int>(pid1), false, false));
944 EXPECT_TRUE(PluginCpuinfoStub(plugin2, cpuData2, static_cast<int>(pid2), false, false));
945 EXPECT_LT(cpuData1.cpu_usage_info().process_cpu_time_ms(), cpuData2.cpu_usage_info().process_cpu_time_ms());
946
947 while (waitpid(-1, NULL, WNOHANG) == 0) {
948 kill(pid1, SIGKILL);
949 kill(pid2, SIGKILL);
950 }
951
952 plugin1.Stop();
953 plugin2.Stop();
954 }
955 } // namespace
956