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) * 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 GetSystemCpuTime(g_systemStat1[0], Hz, systemCpuTime1, systemBootTime1);
551 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr1.c_str(), sysStr1.length());
552 CpuUsageInfo cpuUsageInfo1 = cpuData.cpu_usage_info();
553 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
554 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
555 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), systemCpuTime1);
556 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), systemBootTime1);
557 ASSERT_EQ(cpuUsageInfo1.cores_size(), CORE_NUM);
558 std::vector<int64_t> systemCpuTimeVec1(CORE_NUM);
559 std::vector<int64_t> systemBootTimeVec1(CORE_NUM);
560 for (int i = 1; i <= CORE_NUM; i++) {
561 CpuCoreUsageInfo cpuCoreUsageInfo1 = cpuUsageInfo1.cores()[i - 1];
562 GetSystemCpuTime(g_systemStat1[i], Hz, systemCpuTimeVec1[i-1], systemBootTimeVec1[i-1]);
563 EXPECT_EQ(cpuCoreUsageInfo1.cpu_core(), i-1);
564 EXPECT_EQ(cpuCoreUsageInfo1.prev_system_cpu_time_ms(), 0);
565 EXPECT_EQ(cpuCoreUsageInfo1.prev_system_boot_time_ms(), 0);
566 EXPECT_EQ(cpuCoreUsageInfo1.system_cpu_time_ms(), systemCpuTimeVec1[i-1]);
567 EXPECT_EQ(cpuCoreUsageInfo1.system_boot_time_ms(), systemBootTimeVec1[i-1]);
568 }
569
570 // 存入sysStr2
571 int64_t systemCpuTime2 = 0;
572 int64_t systemBootTime2 = 0;
573 GetSystemCpuTime(g_systemStat2[0], Hz, systemCpuTime2, systemBootTime2);
574 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr2.c_str(), sysStr2.length());
575 CpuUsageInfo cpuUsageInfo2 = cpuData.cpu_usage_info();
576 EXPECT_EQ(cpuUsageInfo2.prev_system_cpu_time_ms(), systemCpuTime1);
577 EXPECT_EQ(cpuUsageInfo2.prev_system_boot_time_ms(), systemBootTime1);
578 EXPECT_EQ(cpuUsageInfo2.system_cpu_time_ms(), systemCpuTime2);
579 EXPECT_EQ(cpuUsageInfo2.system_boot_time_ms(), systemBootTime2);
580 ASSERT_EQ(cpuUsageInfo2.cores_size(), CORE_NUM*2);
581 std::vector<int64_t> systemCpuTimeVec2(CORE_NUM);
582 std::vector<int64_t> systemBootTimeVec2(CORE_NUM);
583 for (int i = 1; i <= CORE_NUM; i++) {
584 CpuCoreUsageInfo cpuCoreUsageInfo2 = cpuUsageInfo2.cores()[CORE_NUM+i-1];
585 GetSystemCpuTime(g_systemStat2[i], Hz, systemCpuTimeVec2[i-1], systemBootTimeVec2[i-1]);
586 EXPECT_EQ(cpuCoreUsageInfo2.cpu_core(), i-1);
587 EXPECT_EQ(cpuCoreUsageInfo2.prev_system_cpu_time_ms(), systemCpuTimeVec1[i-1]);
588 EXPECT_EQ(cpuCoreUsageInfo2.prev_system_boot_time_ms(), systemBootTimeVec1[i-1]);
589 EXPECT_EQ(cpuCoreUsageInfo2.system_cpu_time_ms(), systemCpuTimeVec2[i-1]);
590 EXPECT_EQ(cpuCoreUsageInfo2.system_boot_time_ms(), systemBootTimeVec2[i-1]);
591 }
592
593 // 重复存入sysStr2
594 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr2.c_str(), sysStr2.length());
595 CpuUsageInfo cpuUsageInfo3 = cpuData.cpu_usage_info();
596 EXPECT_EQ(cpuUsageInfo3.prev_system_cpu_time_ms(), systemCpuTime2);
597 EXPECT_EQ(cpuUsageInfo3.prev_system_boot_time_ms(), systemBootTime2);
598 EXPECT_EQ(cpuUsageInfo3.system_cpu_time_ms(), systemCpuTime2);
599 EXPECT_EQ(cpuUsageInfo3.system_boot_time_ms(), systemBootTime2);
600 ASSERT_EQ(cpuUsageInfo3.cores_size(), CORE_NUM*3);
601 std::vector<int64_t> systemCpuTimeVec3(CORE_NUM);
602 std::vector<int64_t> systemBootTimeVec3(CORE_NUM);
603 for (int i = 1; i <= CORE_NUM; i++) {
604 CpuCoreUsageInfo cpuCoreUsageInfo3 = cpuUsageInfo3.cores()[CORE_NUM*2+i-1];
605 GetSystemCpuTime(g_systemStat2[i], Hz, systemCpuTimeVec3[i-1], systemBootTimeVec3[i-1]);
606 EXPECT_EQ(cpuCoreUsageInfo3.cpu_core(), i-1);
607 EXPECT_EQ(cpuCoreUsageInfo3.prev_system_cpu_time_ms(), systemCpuTimeVec2[i-1]);
608 EXPECT_EQ(cpuCoreUsageInfo3.prev_system_boot_time_ms(), systemBootTimeVec2[i-1]);
609 EXPECT_EQ(cpuCoreUsageInfo3.system_cpu_time_ms(), systemCpuTimeVec3[i-1]);
610 EXPECT_EQ(cpuCoreUsageInfo3.system_boot_time_ms(), systemBootTimeVec3[i-1]);
611 }
612 }
613
614 /**
615 * @tc.name: cpu plugin
616 * @tc.desc: cpu system information test for abnormal parameters.
617 * @tc.type: FUNC
618 */
619 HWTEST_F(CpuDataPluginTest, TestPluginSystemBoundary, TestSize.Level1)
620 {
621 CpuData cpuData;
622 CpuDataPlugin cpuPlugin;
623 std::string sysStr;
624 int64_t Hz = cpuPlugin.GetUserHz();
625 int64_t systemCpuTime = 0;
626 int64_t systemBootTime = 0;
627 GetSystemCpuTime(g_systemStat1[0], Hz, systemCpuTime, systemBootTime);
628 // 空字符串
629 sysStr = "";
630 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr.c_str(), sysStr.length());
631 CpuUsageInfo cpuUsageInfo1 = cpuData.cpu_usage_info();
632 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
633 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
634 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), 0);
635 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), 0);
636 ASSERT_EQ(cpuUsageInfo1.cores_size(), 0);
637
638 // 空格字符串
639 sysStr = " ";
640 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr.c_str(), sysStr.length());
641 cpuUsageInfo1 = cpuData.cpu_usage_info();
642 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
643 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
644 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), 0);
645 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), 0);
646 ASSERT_EQ(cpuUsageInfo1.cores_size(), 0);
647
648 // 数据错误
649 sysStr = "1000";
650 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr.c_str(), sysStr.length());
651 cpuUsageInfo1 = cpuData.cpu_usage_info();
652 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
653 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
654 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), 0);
655 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), 0);
656 ASSERT_EQ(cpuUsageInfo1.cores_size(), 0);
657
658 // 数据不够
659 sysStr = "cpu 1234567 2345678 1111111 1193291234 3546789\n"
660 "cpu0 2345678 662862 1966195 1111111 3571925\n"
661 "cpu1 3861506 2345678 1702753 199535158 1752008\n"
662 "cpu2 3549890 1111111 2345678 1234567 1133743\n"
663 "cpu3 3336646 676939 1458898 2345678 854578\n"
664 "cpu4 1111111 601107 2305309 3546789 929594\n"
665 "cpu5 3546789 658673 1234567 197791346 738811\n";
666 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr.c_str(), sysStr.length());
667 cpuUsageInfo1 = cpuData.cpu_usage_info();
668 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
669 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
670 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), 0);
671 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), 0);
672 ASSERT_EQ(cpuUsageInfo1.cores_size(), 0);
673
674 // 多个空格,可以取出正确数据
675 sysStr = "cpu 1234567 2345678 1111111 1193291234 3546789 0 2345678 0 0\n"
676 "cpu0 2345678 662862 1966195 1111111 3571925 0 817371 0 0\n"
677 "cpu1 3861506 2345678 1702753 199535158 1752008 0 401639 0 0\n"
678 "cpu2 3549890 1111111 2345678 1234567 1133743 0 205972 0 0\n"
679 "cpu3 3336646 676939 1458898 2345678 854578 0 2345678 0 0\n"
680 "cpu4 1111111 601107 2305309 3546789 929594 0 1007959 0 0\n"
681 "cpu5 3546789 658673 1234567 197791346 738811 0 49496 0 0\n";
682 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr.c_str(), sysStr.length());
683 cpuUsageInfo1 = cpuData.cpu_usage_info();
684 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), 0);
685 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), 0);
686 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), systemCpuTime);
687 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), systemBootTime);
688 ASSERT_EQ(cpuUsageInfo1.cores_size(), CORE_NUM);
689 std::vector<int64_t> systemCpuTimeVec1(CORE_NUM);
690 std::vector<int64_t> systemBootTimeVec1(CORE_NUM);
691 for (int i = 1; i <= CORE_NUM; i++) {
692 CpuCoreUsageInfo cpuCoreUsageInfo = cpuUsageInfo1.cores()[i - 1];
693 GetSystemCpuTime(g_systemStat1[i], Hz, systemCpuTimeVec1[i-1], systemBootTimeVec1[i-1]);
694 EXPECT_EQ(cpuCoreUsageInfo.cpu_core(), i-1);
695 EXPECT_EQ(cpuCoreUsageInfo.prev_system_cpu_time_ms(), 0);
696 EXPECT_EQ(cpuCoreUsageInfo.prev_system_boot_time_ms(), 0);
697 EXPECT_EQ(cpuCoreUsageInfo.system_cpu_time_ms(), systemCpuTimeVec1[i-1]);
698 EXPECT_EQ(cpuCoreUsageInfo.system_boot_time_ms(), systemBootTimeVec1[i-1]);
699 }
700
701 // 最后一个数据之后没有空格,可以取出正确数据
702 sysStr = "cpu 1234567 2345678 1111111 1193291234 3546789 0 2345678 0 0\n"
703 "cpu0 2345678 662862 1966195 1111111 3571925 0 817371 0 0\n"
704 "cpu1 3861506 2345678 1702753 199535158 1752008 0 401639 0 0\n"
705 "cpu2 3549890 1111111 2345678 1234567 1133743 0 205972 0 0\n"
706 "cpu3 3336646 676939 1458898 2345678 854578 0 2345678 0 0\n"
707 "cpu4 1111111 601107 2305309 3546789 929594 0 1007959 0 0\n"
708 "cpu5 3546789 658673 1234567 197791346 738811 0 49496 0 0\n";
709 cpuPlugin.WriteSystemCpuUsage(cpuData, sysStr.c_str(), sysStr.length());
710 cpuUsageInfo1 = cpuData.cpu_usage_info();
711 EXPECT_EQ(cpuUsageInfo1.prev_system_cpu_time_ms(), systemCpuTime);
712 EXPECT_EQ(cpuUsageInfo1.prev_system_boot_time_ms(), systemBootTime);
713 EXPECT_EQ(cpuUsageInfo1.system_cpu_time_ms(), systemCpuTime);
714 EXPECT_EQ(cpuUsageInfo1.system_boot_time_ms(), systemBootTime);
715 ASSERT_EQ(cpuUsageInfo1.cores_size(), CORE_NUM*2);
716 std::vector<int64_t> systemCpuTimeVec2(CORE_NUM);
717 std::vector<int64_t> systemBootTimeVec2(CORE_NUM);
718 for (int i = 1; i <= CORE_NUM; i++) {
719 CpuCoreUsageInfo cpuCoreUsageInfo = cpuUsageInfo1.cores()[CORE_NUM+i-1];
720 GetSystemCpuTime(g_systemStat1[i], Hz, systemCpuTimeVec2[i-1], systemBootTimeVec2[i-1]);
721 EXPECT_EQ(cpuCoreUsageInfo.cpu_core(), i-1);
722 EXPECT_EQ(cpuCoreUsageInfo.prev_system_cpu_time_ms(), systemCpuTimeVec1[i-1]);
723 EXPECT_EQ(cpuCoreUsageInfo.prev_system_boot_time_ms(), systemBootTimeVec1[i-1]);
724 EXPECT_EQ(cpuCoreUsageInfo.system_cpu_time_ms(), systemCpuTimeVec2[i-1]);
725 EXPECT_EQ(cpuCoreUsageInfo.system_boot_time_ms(), systemBootTimeVec2[i-1]);
726 }
727 }
728
729 /**
730 * @tc.name: cpu plugin
731 * @tc.desc: a part of cpu thread information test.
732 * @tc.type: FUNC
733 */
734 HWTEST_F(CpuDataPluginTest, TestPluginThreadInfo, TestSize.Level1)
735 {
736 std::vector<std::string> threadVec1;
737 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");
738 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");
739 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");
740 threadVec1.push_back("1655 (HeapTaskDaemon) S 1746 1746 0 0 -1 1077936192 1515 0 0 0 3 0 0 0 24 4 19 0");
741 threadVec1.push_back("1656 (ReferenceQueueD) D 1746 1746 0 0 -1 1077936192 24 0 0 0 0 0 0 0 24 4 19 0");
742
743 std::vector<std::string> threadVec2;
744 threadVec2.push_back("1662 (FinalizerDaemon) T 1746 1746 0 0 -1 1077936192 18 0 0 0 0 0 0 0 24 4 19 0");
745 threadVec2.push_back("1663 (FinalizerWatchd) R 1746 1746 0 0 -1 1077936192 5 0 0 0 0 0 0 0 24 4 19 0");
746 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");
747 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");
748 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");
749 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");
750 CpuData cpuData;
751 CpuDataPlugin cpuPlugin;
752 int64_t Hz = cpuPlugin.GetUserHz();
753
754 // 存入threadVec0-4
755 int32_t tid;
756 for (int i = 0; i < FIRST_THREAD_NUM; i++) {
757 auto* threadInfo = cpuData.add_thread_info();
758 tid = atoi(threadVec1[i].substr(0, threadVec1[i].find(" ")).c_str());
759 cpuPlugin.WriteThread(*threadInfo, threadVec1[i].c_str(), threadVec1[i].length(), tid);
760 }
761 ASSERT_EQ(cpuData.thread_info_size(), FIRST_THREAD_NUM);
762 int64_t threadCpuTime1;
763 for (int i = 0; i < FIRST_THREAD_NUM; i++) {
764 threadCpuTime1 = (g_tidStat1[i].stat.utime + g_tidStat1[i].stat.stime) * Hz;
765 ThreadInfo threadInfo1 = cpuData.thread_info()[i];
766 EXPECT_EQ(threadInfo1.tid(), g_tidStat1[i].tid);
767 EXPECT_STREQ(threadInfo1.thread_name().c_str(), g_tidStat1[i].name.c_str());
768 EXPECT_EQ(threadInfo1.thread_state(), g_tidStat1[i].state);
769 EXPECT_EQ(threadInfo1.prev_thread_cpu_time_ms(), 0);
770 EXPECT_EQ(threadInfo1.thread_cpu_time_ms(), threadCpuTime1);
771 }
772
773 // 存入threadVec5-10
774 for (int i = 0; i < SECOND_THREAD_NUM; i++) {
775 auto* threadInfo = cpuData.add_thread_info();
776 tid = atoi(threadVec2[i].substr(0, threadVec2[i].find(" ")).c_str());
777 cpuPlugin.WriteThread(*threadInfo, threadVec2[i].c_str(), threadVec2[i].length(), tid);
778 }
779 ASSERT_EQ(cpuData.thread_info_size(), FIRST_THREAD_NUM+SECOND_THREAD_NUM);
780 std::vector<int64_t> threadCpuTime2;
781 for (int i = 0; i < SECOND_THREAD_NUM; i++) {
782 threadCpuTime2.push_back((g_tidStat2[i].stat.utime + g_tidStat2[i].stat.stime) * Hz);
783 ThreadInfo threadInfo2 = cpuData.thread_info()[i+FIRST_THREAD_NUM];
784 EXPECT_EQ(threadInfo2.tid(), g_tidStat2[i].tid);
785 EXPECT_STREQ(threadInfo2.thread_name().c_str(), g_tidStat2[i].name.c_str());
786 EXPECT_EQ(threadInfo2.thread_state(), g_tidStat2[i].state);
787 EXPECT_EQ(threadInfo2.prev_thread_cpu_time_ms(), 0);
788 EXPECT_EQ(threadInfo2.thread_cpu_time_ms(), threadCpuTime2[i]);
789 }
790
791 // 重复存入threadVec5-10
792 for (int i = 0; i < SECOND_THREAD_NUM; i++) {
793 auto* threadInfo = cpuData.add_thread_info();
794 tid = atoi(threadVec2[i].substr(0, threadVec2[i].find(" ")).c_str());
795 cpuPlugin.WriteThread(*threadInfo, threadVec2[i].c_str(), threadVec2[i].length(), tid);
796 }
797
798 ASSERT_EQ(cpuData.thread_info_size(), FIRST_THREAD_NUM+SECOND_THREAD_NUM*2);
799 int64_t threadCpuTime3;
800 for (int i = 0; i < SECOND_THREAD_NUM; i++) {
801 threadCpuTime3 = (g_tidStat2[i].stat.utime + g_tidStat2[i].stat.stime) * Hz;
802 ThreadInfo threadInfo3 = cpuData.thread_info()[i+FIRST_THREAD_NUM+SECOND_THREAD_NUM];
803 EXPECT_EQ(threadInfo3.tid(), g_tidStat2[i].tid);
804 EXPECT_STREQ(threadInfo3.thread_name().c_str(), g_tidStat2[i].name.c_str());
805 EXPECT_EQ(threadInfo3.thread_state(), g_tidStat2[i].state);
806 EXPECT_EQ(threadInfo3.prev_thread_cpu_time_ms(), threadCpuTime2[i]);
807 EXPECT_EQ(threadInfo3.thread_cpu_time_ms(), threadCpuTime3);
808 }
809 }
810
811 /**
812 * @tc.name: cpu plugin
813 * @tc.desc: cpu thread information test for abnormal parameters.
814 * @tc.type: FUNC
815 */
816 HWTEST_F(CpuDataPluginTest, TestPluginThreadBoundary, TestSize.Level1)
817 {
818 CpuData cpuData;
819 CpuDataPlugin cpuPlugin;
820 std::string threadStr;
821 int thread_info_count = 0;
822 int64_t Hz = cpuPlugin.GetUserHz();
823 int64_t threadCpuTime = (g_tidStat1[0].stat.utime + g_tidStat1[0].stat.stime) * Hz;
824
825 // 空字符串
826 threadStr = "";
827 auto* threadInfo = cpuData.add_thread_info();
828 thread_info_count++;
829 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), 0);
830 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
831
832 // 空格字符串
833 threadStr = " ";
834 threadInfo = cpuData.add_thread_info();
835 thread_info_count++;
836 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), 0);
837 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
838
839 // 数据错误
840 threadStr = "1000";
841 threadInfo = cpuData.add_thread_info();
842 thread_info_count++;
843 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), 0);
844 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
845
846 // 数据不够
847 threadStr = "1209 (skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8";
848 threadInfo = cpuData.add_thread_info();
849 thread_info_count++;
850 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), 0);
851 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
852
853 // 线程名缺失左括号
854 threadStr = "1209 skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8 0 0 20 0 19 0";
855 int32_t tid = atoi(threadStr.substr(0, threadStr.find(" ")).c_str());
856 threadInfo = cpuData.add_thread_info();
857 thread_info_count++;
858 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), tid);
859 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
860 ThreadInfo threadInfo1 = cpuData.thread_info()[thread_info_count-1];
861 EXPECT_EQ(threadInfo1.tid(), g_tidStat1[0].tid);
862 EXPECT_STRNE(threadInfo1.thread_name().c_str(), g_tidStat1[0].name.c_str());
863 EXPECT_EQ(threadInfo1.thread_state(), g_tidStat1[0].state);
864 EXPECT_EQ(threadInfo1.prev_thread_cpu_time_ms(), 0);
865 EXPECT_EQ(threadInfo1.thread_cpu_time_ms(), threadCpuTime);
866
867 // 多个空格,可以取出正确数据
868 threadStr = "1209 (skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8 0 0 20 0 19 0";
869 tid = atoi(threadStr.substr(0, threadStr.find(" ")).c_str());
870 threadInfo = cpuData.add_thread_info();
871 thread_info_count++;
872 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), tid);
873 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
874 threadInfo1 = cpuData.thread_info()[thread_info_count-1];
875 EXPECT_EQ(threadInfo1.tid(), g_tidStat1[0].tid);
876 EXPECT_STREQ(threadInfo1.thread_name().c_str(), g_tidStat1[0].name.c_str());
877 EXPECT_EQ(threadInfo1.thread_state(), g_tidStat1[0].state);
878 EXPECT_EQ(threadInfo1.prev_thread_cpu_time_ms(), threadCpuTime);
879 EXPECT_EQ(threadInfo1.thread_cpu_time_ms(), threadCpuTime);
880
881 // 最后一个数据之后没有空格,可以取出正确数据
882 threadStr = "1209 (skytone:service) R 1746 1746 0 0 -1 1077936448 10399 0 1 0 22 8 0 0 20";
883 tid = atoi(threadStr.substr(0, threadStr.find(" ")).c_str());
884 threadInfo = cpuData.add_thread_info();
885 thread_info_count++;
886 cpuPlugin.WriteThread(*threadInfo, threadStr.c_str(), threadStr.length(), tid);
887 ASSERT_EQ(cpuData.thread_info_size(), thread_info_count);
888 threadInfo1 = cpuData.thread_info()[thread_info_count-1];
889 EXPECT_EQ(threadInfo1.tid(), g_tidStat1[0].tid);
890 EXPECT_STREQ(threadInfo1.thread_name().c_str(), g_tidStat1[0].name.c_str());
891 EXPECT_EQ(threadInfo1.thread_state(), g_tidStat1[0].state);
892 EXPECT_EQ(threadInfo1.prev_thread_cpu_time_ms(), threadCpuTime);
893 EXPECT_EQ(threadInfo1.thread_cpu_time_ms(), threadCpuTime);
894 }
895
ExecuteBin(const std::string & bin,const std::vector<std::string> & args)896 bool ExecuteBin(const std::string& bin, const std::vector<std::string>& args)
897 {
898 std::vector<char*> argv;
899 for (size_t i = 0; i < args.size(); i++) {
900 argv.push_back(const_cast<char*>(args[i].c_str()));
901 }
902 argv.push_back(nullptr); // last item in argv must be NULL
903
904 int retval = execvp(bin.c_str(), argv.data());
905 CHECK_TRUE(retval != -1, false, "execv %s failed, %d!", bin.c_str(), errno);
906 _exit(EXIT_FAILURE);
907 abort(); // never should be here.
908 return true;
909 }
910
911 /**
912 * @tc.name: cpu plugin
913 * @tc.desc: test ParseCpuInfo for pid
914 * @tc.type: FUNC
915 */
916 HWTEST_F(CpuDataPluginTest, TestPid, TestSize.Level1)
917 {
918 CpuDataPlugin plugin1, plugin2;
919 CpuData cpuData1, cpuData2;
920
921 std::string cmd = "chmod 777 " + DEFAULT_BIN_PATH;
922 system(cmd.c_str());
923
924 pid_t pid1 = fork();
925 if (pid1 == 0) {
926 // set 0, not to do
927 std::vector<std::string> argv = {"childpidtest1", "0"};
928 ASSERT_TRUE(ExecuteBin(DEFAULT_BIN_PATH, argv));
929 }
930 pid_t pid2 = fork();
931 if (pid2 == 0) {
932 // set 1, consume cpu
933 std::vector<std::string> argv = {"childpidtest2", "1"};
934 ASSERT_TRUE(ExecuteBin(DEFAULT_BIN_PATH, argv));
935 }
936
937 sleep(1); // 睡眠1s,确保pid1进入睡眠状态,pid2进入while循环
938 EXPECT_TRUE(PluginCpuinfoStub(plugin1, cpuData1, static_cast<int>(pid1), false, false));
939 EXPECT_TRUE(PluginCpuinfoStub(plugin2, cpuData2, static_cast<int>(pid2), false, false));
940 EXPECT_LT(cpuData1.cpu_usage_info().process_cpu_time_ms(), cpuData2.cpu_usage_info().process_cpu_time_ms());
941
942 while (waitpid(-1, nullptr, WNOHANG) == 0) {
943 kill(pid1, SIGKILL);
944 kill(pid2, SIGKILL);
945 }
946
947 plugin1.Stop();
948 plugin2.Stop();
949 }
950 } // namespace
951