!357 enhance process plugin

Merge pull request !357 from jiangyuan0000/master
This commit is contained in:
openharmony_ci 2022-06-28 13:58:49 +00:00 committed by Gitee
commit cb08c6176d
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
24 changed files with 1055 additions and 69 deletions

View File

@ -62,6 +62,7 @@ Note:If the text contains special characters, please escape them according to th
<filteritem type="filepath" name="device/plugins/cpu_plugin/test/resources/.*" desc="test resource file, no license header"/>
<filteritem type="filepath" name="device/plugins/diskio_plugin/test/resources/.*" desc="test resource file, no license header"/>
<filteritem type="filepath" name="device/plugins/network_plugin/test/utresources/.*" desc="test resource file, no license header"/>
<filteritem type="filepath" name="device/plugins/process_plugin/test/resources/.*" desc="test resource file, no license header"/>
<filteritem type="filepath" name="device/plugins/api/test/fuzztest/plugindestroysessioncmd_fuzzer/corpus/init" desc="test resource file, no license header"/>
<filteritem type="filepath" name="device/plugins/api/test/fuzztest/pluginstartsessioncmd_fuzzer/corpus/init" desc="test resource file, no license header"/>
<filteritem type="filepath" name="device/plugins/api/test/fuzztest/plugincreatesessioncmd_fuzzer/corpus/init" desc="test resource file, no license header"/>
@ -86,6 +87,7 @@ Note:If the text contains special characters, please escape them according to th
<filteritem type="filepath" name="device/plugins/cpu_plugin/test/resources/.*" desc="test resource file, no copyright header"/>
<filteritem type="filepath" name="device/plugins/diskio_plugin/test/resources/.*" desc="test resource file, no copyright header"/>
<filteritem type="filepath" name="device/plugins/network_plugin/test/utresources/.*" desc="test resource file, no copyright header"/>
<filteritem type="filepath" name="device/plugins/process_plugin/test/resources/.*" desc="test resource file, no copyright header"/>
<filteritem type="filepath" name="device/plugins/api/test/fuzztest/plugindestroysessioncmd_fuzzer/corpus/init" desc="test resource file, no copyright header"/>
<filteritem type="filepath" name="device/plugins/api/test/fuzztest/pluginstartsessioncmd_fuzzer/corpus/init" desc="test resource file, no copyright header"/>
<filteritem type="filepath" name="device/plugins/api/test/fuzztest/plugincreatesessioncmd_fuzzer/corpus/init" desc="test resource file, no copyright header"/>

View File

@ -61,6 +61,7 @@ group("unittest") {
"plugins/hiperf_plugin/test:unittest",
"plugins/memory_plugin/test:unittest",
"plugins/network_plugin/test:unittest",
"plugins/process_plugin/test:unittest",
"services/ipc/test:unittest",
"services/plugin_service/test:unittest",
"services/profiler_service/test:unittest",

View File

@ -117,10 +117,23 @@
<option name="push" value="plugins/native_daemon/test/unittest/resource/testdata/dwarf/hiperf_643_644_sample_record_213_6754913387560.dump -> /data/test/resource/testdata/dwarf/" src="res"/>
</preparer>
</target>
<target name="trace_converter_ut">
<target name="processplugin_ut">
<preparer>
<option name="push" value="plugins/ftrace_plugin/tools/trace_converter/test/unittest/resource/ExpectTraceConverterData.txt -> /data/test/resource/testdata/" src="res"/>
<option name="push" value="plugins/ftrace_plugin/tools/trace_converter/test/unittest/resource/TraceData.ftrace -> /data/test/resource/testdata/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/stat -> /data/local/tmp/resources/proc/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/11/cmdline -> /data/local/tmp/resources/proc/11/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/11/io -> /data/local/tmp/resources/proc/11/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/11/smaps_rollup -> /data/local/tmp/resources/proc/11/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/11/stat -> /data/local/tmp/resources/proc/11/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/11/status -> /data/local/tmp/resources/proc/11/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/11/task/11/cmdline -> /data/local/tmp/resources/proc/11/task/11/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/1872/cmdline -> /data/local/tmp/resources/proc/1872/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/1872/io -> /data/local/tmp/resources/proc/1872/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/1872/smaps_rollup -> /data/local/tmp/resources/proc/1872/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/1872/stat -> /data/local/tmp/resources/proc/1872/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/1872/status -> /data/local/tmp/resources/proc/1872/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/1872/task/1872/cmdline -> /data/local/tmp/resources/proc/1872/task/1872/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/1872/task/1873/cmdline -> /data/local/tmp/resources/proc/1872/task/1873/" src="res"/>
<option name="push" value="plugins/process_plugin/test/resources/proc/1872/task/1965/cmdline -> /data/local/tmp/resources/proc/1872/task/1965/" src="res"/>
</preparer>
</target>
</configuration>

View File

@ -47,37 +47,47 @@ public:
int Start(const uint8_t* configData, uint32_t configSize);
int Report(uint8_t* configData, uint32_t configSize);
int Stop();
void SetPath(char* path)
int64_t GetUserHz();
// for UT
void SetPath(std::string path)
{
testpath_ = path;
path_ = path;
};
void WriteProcesseList(ProcessData& data);
void WriteProcinfoByPidfds(ProcessInfo* processinfo, int32_t pid);
DIR* OpenDestDir(const char* dirPath);
int32_t GetValidPid(DIR* dirp);
// for test change static
int ParseNumber(std::string line);
private:
ProcessConfig protoConfig_;
std::unique_ptr<uint8_t[]> buffer_;
std::unordered_map<int32_t, std::vector<int>> pidFds_;
std::vector<int32_t> seenPids_;
char* testpath_;
int32_t err_;
int32_t ReadFile(int fd);
bool WriteProcesseList(ProcessData& data);
DIR* OpenDestDir(const char* dirPath);
int32_t GetValidPid(DIR* dirp);
std::vector<int> OpenProcPidFiles(int32_t pid);
int32_t ReadProcPidFile(int32_t pid, const char* pFileName);
void WriteProcessInfo(ProcessData& data, int32_t pid);
void SetEmptyProcessInfo(ProcessInfo* processinfo);
void WriteProcess(ProcessInfo* processinfo, const char* pFile, uint32_t fileLen, int32_t pid);
void SetProcessInfo(ProcessInfo* processinfo, int key, const char* word);
bool BufnCmp(const char* src, int srcLen, const char* key, int keyLen);
bool addPidBySort(int32_t pid);
int GetProcStatusId(const char* src, int srcLen);
bool WriteCpuUsageData(int pid, CpuInfo* protoc);
bool ReadCpuUsage(int pid, CpuInfo* protoc, uint64_t& cpuTime);
uint32_t GetCpuUsageData(const std::string& line, CpuInfo* protoc, uint64_t& cpuTime);
bool ReadBootTime(int pid, CpuInfo* protoc, uint64_t& bootTime);
uint32_t GetBootData(const std::string& line, CpuInfo* protoc, uint64_t& bootTime);
bool WriteThreadData(int pid, CpuInfo* protoc);
bool FindFirstNum(char** p);
bool GetValidValue(char* p, uint64_t& num);
bool FindFirstSpace(char** p);
bool GetDiskioData(std::string& line, DiskioInfo* protoc);
bool WriteDiskioData(int pid, DiskioInfo* protoc);
bool WritePssData(int pid, PssInfo* protoc);
ProcessConfig protoConfig_;
std::unique_ptr<uint8_t[]> buffer_;
std::vector<int32_t> pids_;
std::string path_;
int32_t err_;
std::unordered_map<int, uint64_t> cpuTime_ = {};
std::unordered_map<int, uint64_t> bootTime_ = {};
};
#endif

View File

@ -15,6 +15,8 @@
#include "process_data_plugin.h"
#include <sstream>
#include <fstream>
#include <iostream>
#include "buffer_splitter.h"
#include "securec.h"
@ -22,12 +24,17 @@
namespace {
constexpr size_t READ_BUFFER_SIZE = 1024 * 16;
constexpr int DEC_BASE = 10;
constexpr int STAT_COUNT = 13;
constexpr int CPU_USER_HZ_L = 100;
constexpr int CPU_USER_HZ_H = 1000;
constexpr int CPU_HZ_H = 10;
const int PERCENT = 100;
} // namespace
ProcessDataPlugin::ProcessDataPlugin()
: buffer_(new (std::nothrow) uint8_t[READ_BUFFER_SIZE]), err_(-1)
{
SetPath(const_cast<char*>("/proc"));
SetPath("/proc/");
}
ProcessDataPlugin::~ProcessDataPlugin()
@ -39,7 +46,6 @@ ProcessDataPlugin::~ProcessDataPlugin()
return;
}
int ProcessDataPlugin::Start(const uint8_t* configData, uint32_t configSize)
{
if (buffer_ == nullptr) {
@ -56,12 +62,6 @@ int ProcessDataPlugin::Start(const uint8_t* configData, uint32_t configSize)
return RET_SUCC;
}
int ProcessDataPlugin::ParseNumber(std::string line)
{
return atoi(line.substr(line.find_first_of("01234567890")).c_str());
}
int ProcessDataPlugin::Report(uint8_t* data, uint32_t dataSize)
{
ProcessData dataProto;
@ -83,25 +83,14 @@ int ProcessDataPlugin::Report(uint8_t* data, uint32_t dataSize)
int ProcessDataPlugin::Stop()
{
pids_.clear();
cpuTime_.clear();
bootTime_.clear();
HILOG_INFO(LOG_CORE, "%s:stop success!", __func__);
return 0;
}
int32_t ProcessDataPlugin::ReadFile(int fd)
{
if ((buffer_.get() == nullptr) || (fd == -1)) {
return RET_FAIL;
}
int readsize = pread(fd, buffer_.get(), READ_BUFFER_SIZE - 1, 0);
if (readsize <= 0) {
HILOG_ERROR(LOG_CORE, "%s:failed to read(%d), errno=%d", __func__, fd, errno);
err_ = errno;
return RET_FAIL;
}
return readsize;
}
DIR* ProcessDataPlugin::OpenDestDir(const char* dirPath)
{
DIR* destDir = nullptr;
@ -137,7 +126,7 @@ int32_t ProcessDataPlugin::ReadProcPidFile(int32_t pid, const char* pFileName)
int fd = -1;
ssize_t bytesRead = 0;
if (snprintf_s(fileName, sizeof(fileName), sizeof(fileName) - 1, "%s/%d/%s", testpath_, pid, pFileName) < 0) {
if (snprintf_s(fileName, sizeof(fileName), sizeof(fileName) - 1, "%s%d/%s", path_.c_str(), pid, pFileName) < 0) {
HILOG_ERROR(LOG_CORE, "%s:snprintf_s error", __func__);
}
if (realpath(fileName, realPath) == nullptr) {
@ -184,12 +173,12 @@ bool ProcessDataPlugin::BufnCmp(const char* src, int srcLen, const char* key, in
bool ProcessDataPlugin::addPidBySort(int32_t pid)
{
auto pidsEnd = seenPids_.end();
auto it = std::lower_bound(seenPids_.begin(), pidsEnd, pid);
auto pidsEnd = pids_.end();
auto it = std::lower_bound(pids_.begin(), pidsEnd, pid);
if (it != pidsEnd && *it == pid) {
return false;
}
it = seenPids_.insert(it, std::move(pid));
it = pids_.insert(it, std::move(pid));
return true;
}
@ -209,23 +198,47 @@ void ProcessDataPlugin::WriteProcess(ProcessInfo* processinfo, const char* pFile
return;
}
processinfo->set_name(totalbuffer.CurWord(), totalbuffer.CurWordSize());
} else if (BufnCmp(totalbuffer.CurWord(), totalbuffer.CurWordSize(), "Tgid", strlen("Tgid"))) {
} else if (BufnCmp(totalbuffer.CurWord(), totalbuffer.CurWordSize(), "Pid", strlen("Pid"))) {
totalbuffer.NextWord('\n');
if (!totalbuffer.CurWord()) {
return;
}
char* end = nullptr;
int32_t value = static_cast<int32_t>(strtoul(totalbuffer.CurWord(), &end, DEC_BASE));
if (value <= 0) {
if (value < 0) {
HILOG_ERROR(LOG_CORE, "%s:strtoull value failed", __func__);
}
processinfo->set_pid(value);
} else if (BufnCmp(totalbuffer.CurWord(), totalbuffer.CurWordSize(), "PPid", strlen("PPid"))) {
totalbuffer.NextWord('\n');
if (!totalbuffer.CurWord()) {
return;
}
char* end = nullptr;
int32_t value = static_cast<int32_t>(strtoul(totalbuffer.CurWord(), &end, DEC_BASE));
if (value < 0) {
HILOG_ERROR(LOG_CORE, "%s:strtoull value failed", __func__);
}
processinfo->set_ppid(value);
} else if (BufnCmp(totalbuffer.CurWord(), totalbuffer.CurWordSize(), "Uid", strlen("Uid"))) {
totalbuffer.NextWord('\n');
if (!totalbuffer.CurWord()) {
return;
}
std::string curWord = std::string(totalbuffer.CurWord(), totalbuffer.CurWordSize());
curWord = curWord.substr(0, curWord.find(" "));
char* end = nullptr;
int32_t value = static_cast<int32_t>(strtoul(curWord.c_str(), &end, DEC_BASE));
if (value < 0) {
HILOG_ERROR(LOG_CORE, "%s:strtoull value failed", __func__);
}
processinfo->set_uid(value);
break;
}
totalbuffer.NextWord('\n');
if (!totalbuffer.CurWord()) {
continue;
} else {
totalbuffer.NextWord('\n');
if (!totalbuffer.CurWord()) {
continue;
}
}
} while (totalbuffer.NextLine());
// update process name
@ -235,17 +248,10 @@ void ProcessDataPlugin::WriteProcess(ProcessInfo* processinfo, const char* pFile
}
}
void ProcessDataPlugin::SetEmptyProcessInfo(ProcessInfo* processinfo)
{
processinfo->set_pid(-1);
processinfo->set_name("null");
}
void ProcessDataPlugin::WriteProcessInfo(ProcessData& data, int32_t pid)
{
int32_t ret = ReadProcPidFile(pid, "status");
if (ret == RET_FAIL) {
SetEmptyProcessInfo(data.add_processesinfo());
return;
}
if ((buffer_.get() == nullptr) || (ret == 0)) {
@ -253,24 +259,330 @@ void ProcessDataPlugin::WriteProcessInfo(ProcessData& data, int32_t pid)
}
auto* processinfo = data.add_processesinfo();
WriteProcess(processinfo, (char*)buffer_.get(), ret, pid);
if (protoConfig_.report_cpu()) {
auto cpuProto = processinfo->mutable_cpuinfo();
std::vector<uint64_t> cpuUsageVec;
std::vector<uint64_t> bootTime;
WriteCpuUsageData(pid, cpuProto);
WriteThreadData(pid, cpuProto);
}
if (protoConfig_.report_diskio()) {
auto diskProto = processinfo->mutable_diskinfo();
WriteDiskioData(pid, diskProto);
}
if (protoConfig_.report_pss()) {
auto pssProto = processinfo->mutable_pssinfo();
WritePssData(pid, pssProto);
}
}
void ProcessDataPlugin::WriteProcesseList(ProcessData& data)
bool ProcessDataPlugin::WriteProcesseList(ProcessData& data)
{
DIR* procDir = nullptr;
procDir = OpenDestDir(testpath_);
procDir = OpenDestDir(path_.c_str());
if (procDir == nullptr) {
return;
return false;
}
seenPids_.clear();
pids_.clear();
while (int32_t pid = GetValidPid(procDir)) {
CHECK_TRUE(pid > 0, false, "%s: get pid[%d] failed", __func__, pid);
addPidBySort(pid);
}
for (unsigned int i = 0; i < seenPids_.size(); i++) {
WriteProcessInfo(data, seenPids_[i]);
for (unsigned int i = 0; i < pids_.size(); i++) {
WriteProcessInfo(data, pids_[i]);
}
closedir(procDir);
return true;
}
bool ProcessDataPlugin::WriteThreadData(int pid, CpuInfo* protoc)
{
DIR* procDir = nullptr;
std::string path = path_ + std::to_string(pid) + "/task";
procDir = OpenDestDir(path.c_str());
if (procDir == nullptr) {
return false;
}
uint32_t i = 0;
while (int32_t tid = GetValidPid(procDir)) {
CHECK_TRUE(tid > 0, false, "%s: get pid[%d] failed", __func__, tid);
i++;
}
protoc->set_thread_sum(i);
closedir(procDir);
return true;
}
int64_t ProcessDataPlugin::GetUserHz()
{
int64_t hz = -1;
int64_t user_hz = sysconf(_SC_CLK_TCK);
switch (user_hz) {
case CPU_USER_HZ_L:
hz = CPU_HZ_H;
break;
case CPU_USER_HZ_H:
hz = 1;
break;
default:
break;
}
return hz;
}
bool ProcessDataPlugin::WriteCpuUsageData(int pid, CpuInfo* protoc)
{
uint64_t prevCpuTime = 0;
uint64_t cpuTime = 0;
uint64_t prevBootTime = 0;
uint64_t bootTime = 0;
double usage = 0.0;
ReadCpuUsage(pid, protoc, cpuTime);
ReadBootTime(pid, protoc, bootTime);
if (cpuTime_.find(pid) != cpuTime_.end()) {
prevCpuTime = cpuTime_[pid];
}
if (bootTime_.find(pid) != bootTime_.end()) {
prevBootTime = bootTime_[pid];
}
if (bootTime - prevBootTime == 0 || bootTime == 0) {
protoc->set_cpu_usage(0);
return false;
}
if (prevCpuTime == 0) {
usage = static_cast<double>(cpuTime) / (bootTime);
} else {
usage = static_cast<double>(cpuTime - prevCpuTime) / (bootTime - prevBootTime);
}
protoc->set_cpu_usage(usage * PERCENT);
protoc->set_cpu_time_ms(cpuTime);
cpuTime_[pid] = cpuTime;
bootTime_[pid] = bootTime;
return true;
}
bool ProcessDataPlugin::ReadBootTime(int pid, CpuInfo* protoc, uint64_t& bootTime)
{
std::string path = path_ + "stat";
std::ifstream input(path, std::ios::in);
if (input.fail()) {
HILOG_ERROR(LOG_CORE, "%s open %s failed, errno = %d", __func__, path.c_str(), errno);
return false;
}
do {
if (!input.good()) {
return false;
}
std::string line;
getline(input, line);
auto pos = line.find("cpu ");
if (pos != std::string::npos) {
line += '\n';
GetBootData(line, protoc, bootTime);
}
} while (0);
input.close();
return true;
}
uint32_t ProcessDataPlugin::GetBootData(const std::string& line, CpuInfo* protoc, uint64_t& bootTime)
{
uint64_t num;
uint32_t count = 0;
char* end = nullptr;
char* pTmp = const_cast<char*>(line.c_str());
constexpr uint32_t cntVec = 8;
std::vector<uint64_t> bootTimeVec;
bootTime = 0;
while (pTmp != nullptr && *pTmp != '\n') {
CHECK_TRUE(FindFirstNum(&pTmp), count, "%s: FindFirstNum failed", __func__);
num = strtoull(pTmp, &end, DEC_BASE);
CHECK_TRUE(num >= 0, count, "%s:strtoull failed", __func__);
bootTimeVec.push_back(num);
bootTime += num;
pTmp = end;
if (++count >= cntVec) {
break;
}
}
bootTime = bootTime * GetUserHz();
return count;
}
bool ProcessDataPlugin::ReadCpuUsage(int pid, CpuInfo* protoc, uint64_t& cpuTime)
{
std::string path = path_ + std::to_string(pid) + "/stat";
std::ifstream input(path, std::ios::in);
if (input.fail()) {
HILOG_ERROR(LOG_CORE, "%s open %s failed, errno = %d", __func__, path.c_str(), errno);
return false;
}
do {
if (!input.good()) {
return false;
}
std::string line;
getline(input, line);
line += '\n';
GetCpuUsageData(line, protoc, cpuTime);
} while (0);
input.close();
return true;
}
uint32_t ProcessDataPlugin::GetCpuUsageData(const std::string& line, CpuInfo* protoc, uint64_t& cpuTime)
{
uint64_t num;
uint32_t count = 0;
char* end = nullptr;
char* pTmp = const_cast<char*>(line.c_str());
int i = 0;
constexpr uint32_t cntVec = 4;
while (FindFirstSpace(&pTmp)) {
pTmp++;
if (++i >= STAT_COUNT) {
break;
}
}
std::vector<uint64_t> cpuUsageVec;
cpuTime = 0;
while (pTmp != nullptr && *pTmp != '\n') {
CHECK_TRUE(FindFirstNum(&pTmp), count, "%s: FindFirstNum failed", __func__);
num = strtoull(pTmp, &end, DEC_BASE);
cpuUsageVec.push_back(num);
cpuTime += num;
pTmp = end;
if (++count >= cntVec) {
break;
}
}
cpuTime = cpuTime * GetUserHz();
return count;
}
bool ProcessDataPlugin::WriteDiskioData(int pid, DiskioInfo* protoc)
{
std::string path = path_ + std::to_string(pid) + "/io";
std::ifstream input(path, std::ios::in);
if (input.fail()) {
return false;
}
do {
if (!input.good()) {
return false;
}
std::string line;
getline(input, line);
line += '\n';
GetDiskioData(line, protoc);
} while (!input.eof());
input.close();
return true;
}
bool ProcessDataPlugin::GetDiskioData(std::string& line, DiskioInfo* protoc)
{
char* pTmp = const_cast<char*>(line.c_str());
CHECK_NOTNULL(pTmp, false, "param invalid!");
uint64_t num;
if (!std::strncmp(pTmp, "rchar:", strlen("rchar:"))) {
CHECK_TRUE(GetValidValue(pTmp, num), false, "%s: get rchar failed", __func__);
protoc->set_rchar(num);
} else if (!std::strncmp(pTmp, "wchar:", strlen("wchar:"))) {
CHECK_TRUE(GetValidValue(pTmp, num), false, "%s: get wchar failed", __func__);
protoc->set_wchar(num);
} else if (!std::strncmp(pTmp, "syscr:", strlen("syscr:"))) {
CHECK_TRUE(GetValidValue(pTmp, num), false, "%s: get syscr failed", __func__);
protoc->set_syscr(num);
} else if (!std::strncmp(pTmp, "syscw:", strlen("syscw:"))) {
CHECK_TRUE(GetValidValue(pTmp, num), false, "%s: get syscw failed", __func__);
protoc->set_syscw(num);
} else if (!std::strncmp(pTmp, "read_bytes:", strlen("read_bytes:"))) {
CHECK_TRUE(GetValidValue(pTmp, num), false, "%s: get read_bytes failed", __func__);
protoc->set_rbytes(num);
} else if (!std::strncmp(pTmp, "write_bytes:", strlen("write_bytes:"))) {
CHECK_TRUE(GetValidValue(pTmp, num), false, "%s: get write_bytes failed", __func__);
protoc->set_wbytes(num);
} else if (!std::strncmp(pTmp, "cancelled_write_bytes:", strlen("cancelled_write_bytes:"))) {
CHECK_TRUE(GetValidValue(pTmp, num), false, "%s: get cancelled_write_bytes failed", __func__);
protoc->set_cancelled_wbytes(num);
}
return true;
}
bool ProcessDataPlugin::FindFirstSpace(char** p)
{
CHECK_NOTNULL(*p, false, "ProcessDataPlugin:%s", __func__);
while (**p != ' ') {
if (**p == '\0' || **p == '\n') {
return false;
}
(*p)++;
}
return true;
}
bool ProcessDataPlugin::FindFirstNum(char** p)
{
CHECK_NOTNULL(*p, false, "ProcessDataPlugin:%s", __func__);
while (**p > '9' || **p < '0') {
if (**p == '\0' || **p == '\n') {
return false;
}
(*p)++;
}
return true;
}
bool ProcessDataPlugin::GetValidValue(char* p, uint64_t& num)
{
char* end = nullptr;
CHECK_TRUE(FindFirstNum(&p), false, "%s: FindFirstNum failed", __func__);
num = strtoull(p, &end, DEC_BASE);
CHECK_TRUE(num >= 0, false, "%s:strtoull failed", __func__);
return true;
}
// read /proc/pid/smaps_rollup
bool ProcessDataPlugin::WritePssData(int pid, PssInfo* protoc)
{
std::string path = path_ + std::to_string(pid) + "/smaps_rollup";
std::ifstream input(path, std::ios::in);
if (input.fail()) {
HILOG_ERROR(LOG_CORE, "%s open %s failed, errno = %d", __func__, path.c_str(), errno);
return false;
}
do {
if (!input.good()) {
return false;
}
std::string line;
getline(input, line);
line += '\n';
std::string::size_type pos = 0u;
if ((pos = line.find("Pss:", pos)) != std::string::npos) {
char* pTmp = const_cast<char*>(line.c_str());
uint64_t num;
CHECK_TRUE(GetValidValue(pTmp, num), false, "%s: FindFirstNum failed", __func__);
protoc->set_pss_info(num);
return true;
}
} while (!input.eof());
input.close();
return false;
}

View File

@ -0,0 +1,56 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
import("../../../base/config.gni")
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
config("module_private_config") {
visibility = [ ":*" ]
if (current_toolchain != host_toolchain) {
defines = [ "HAVE_HILOG" ]
}
}
ohos_unittest("processplugin_ut") {
module_out_path = module_output_path
sources = [ "unittest/process_plugin_unittest.cpp" ]
deps = [
"${OHOS_PROFILER_DIR}/device/plugins/process_plugin:processplugin",
"${OHOS_PROFILER_DIR}/protos/types/plugins/process_data:process_data_cpp",
"//third_party/bounds_checking_function:libsec_static",
"//third_party/googletest:gtest_main",
]
include_dirs = [
"../include",
"../../../memory_plugin/include",
"${OHOS_PROFILER_DIR}/interfaces/kits",
"${OHOS_PROFILER_DIR}/device/base/include",
"//third_party/googletest/googletest/include/gtest",
"//third_party/bounds_checking_function/include",
]
cflags = [
"-Wno-inconsistent-missing-override",
"-Dprivate=public", #allow test code access private members
]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
configs = [ ":module_private_config" ]
subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}"
part_name = "${OHOS_PROFILER_PART_NAME}"
resource_config_file = "${OHOS_PROFILER_DIR}/device/ohos_test.xml"
}
group("unittest") {
testonly = true
deps = [ ":processplugin_ut" ]
}

View File

@ -0,0 +1 @@
test

View File

@ -0,0 +1,7 @@
rchar: 479
wchar: 577
syscr: 1973
syscw: 8092
read_bytes: 2574
write_bytes: 50
cancelled_write_bytes: 91

View File

@ -0,0 +1,21 @@
00ac0000-ffff1000 ---p 00000000 00:00 0 [rollup]
Rss: 4136 kB
Pss: 1499 kB
Pss_Anon: 700 kB
Pss_File: 765 kB
Pss_Shmem: 34 kB
Shared_Clean: 2584 kB
Shared_Dirty: 132 kB
Private_Clean: 720 kB
Private_Dirty: 700 kB
Referenced: 4112 kB
Anonymous: 700 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB

View File

@ -0,0 +1 @@
11 (test) S 1 1865 1780 1025 1780 4194304 3233 0 457 0 60 10 20 30 20 0 7 0 4394 726278144 0 18446744073709551615 1 1 0 0 0 0 0 16781312 16386 0 0 0 17 5 0 0 5 0 0 0 0 0 0 0 0 0 0

View File

@ -0,0 +1,37 @@
Name: test
Umask: 0000
State: I (idle)
Tgid: 11
Ngid: 0
Pid: 11
PPid: 2
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 64
Groups:
NStgid: 11
NSpid: 11
NSpgid: 0
NSsid: 0
Threads: 1
SigQ: 0/62967
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: ffffffffffffffff
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Speculation_Store_Bypass: thread vulnerable
Cpus_allowed: 3f
Cpus_allowed_list: 0-5
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 18962428
nonvoluntary_ctxt_switches: 39

View File

@ -0,0 +1 @@
test

View File

@ -0,0 +1 @@
ibus-x11

View File

@ -0,0 +1,7 @@
rchar: 7201784
wchar: 3168
syscr: 54150
syscw: 35
read_bytes: 22499328
write_bytes: 0
cancelled_write_bytes: 0

View File

@ -0,0 +1,21 @@
00ac0000-ffff1000 ---p 00000000 00:00 0 [rollup]
Rss: 4136 kB
Pss: 230 kB
Pss_Anon: 700 kB
Pss_File: 765 kB
Pss_Shmem: 34 kB
Shared_Clean: 2584 kB
Shared_Dirty: 132 kB
Private_Clean: 720 kB
Private_Dirty: 700 kB
Referenced: 4112 kB
Anonymous: 700 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB

View File

@ -0,0 +1 @@
1872 (ibus-x11) S 1 1865 1780 1025 1780 4194304 3233 0 457 0 70 10 50 30 20 0 7 0 4394 726278144 0 18446744073709551615 1 1 0 0 0 0 0 16781312 16386 0 0 0 17 5 0 0 5 0 0 0 0 0 0 0 0 0 0

View File

@ -0,0 +1,37 @@
Name: ibus-x11
Umask: 0000
State: S (sleeping)
Tgid: 1872
Ngid: 0
Pid: 1872
PPid: 0
TracerPid: 0
Uid: 1 0 0 0
Gid: 0 0 0 0
FDSize: 64
Groups:
NStgid: 2
NSpid: 2
NSpgid: 0
NSsid: 0
Threads: 1
SigQ: 0/62970
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: ffffffffffffffff
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Speculation_Store_Bypass: thread vulnerable
Cpus_allowed: 3f
Cpus_allowed_list: 0-5
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 3372
nonvoluntary_ctxt_switches: 1

View File

@ -0,0 +1 @@
ibus-x11

View File

@ -0,0 +1 @@
ibus-x1:disk$0

View File

@ -0,0 +1 @@
ibus-x1:disk$1

View File

@ -0,0 +1,14 @@
cpu 24875428 3952448 11859815 1193297105 8980661 0 2607250 0 0 0
cpu0 4165400 662862 1966195 196987024 3571925 0 817371 0 0 0
cpu1 3861506 676578 1702753 199535158 1752008 0 401639 0 0 0
cpu2 3549890 676286 1544630 200640747 1133743 0 205972 0 0 0
cpu3 3336646 676939 1458898 201176432 854578 0 124812 0 0 0
cpu4 4566158 601107 2305309 197166395 929594 0 1007959 0 0 0
cpu5 5395826 658673 2882028 197791346 738811 0 49496 0 0 0
intr 1770859348 7 4 0 0 0 0 0 0 1 11 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 171 59725591 981403168 19 439482 559268 457611 427943 581724 453376 45 20991 669 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 2926398868
btime 1620093904
processes 18239603
procs_running 1
procs_blocked 0
softirq 2254950393 2090427 450858980 2885663 985716628 59484869 0 134917257 208251538 45883 410699148

View File

@ -0,0 +1,410 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cinttypes>
#include <hwext/gtest-ext.h>
#include <hwext/gtest-tag.h>
#include <dlfcn.h>
#include "process_data_plugin.h"
#include "plugin_module_api.h"
using namespace testing::ext;
namespace {
const std::string DEFAULT_TEST_PATH = "/data/local/tmp/resources";
#if defined(__arm__)
const std::string SO_PATH = "/system/lib/libprocessplugin.z.so";
#elif defined(__aarch64__)
const std::string SO_PATH = "/system/lib64/libprocessplugin.z.so";
#endif
constexpr uint32_t BUF_SIZE = 4 * 1024 * 1024;
const int PERCENT = 100;
constexpr int PROCESS_NUM = 2;
constexpr int THREAD_NUM = 3;
std::string g_path = "";
std::string g_testPath = "";
std::shared_ptr<ProcessDataPlugin> processPlugin = nullptr;
struct PssData {
int32_t pss_info;
};
struct DiskioData {
int64_t rchar;
int64_t wchar;
int64_t syscr;
int64_t syscw;
int64_t rbytes;
int64_t wbytes;
int64_t cancelled_wbytes;
};
struct CpuData {
double cpu_usage;
int32_t thread_sum;
int64_t cpu_time_ms;
};
struct ProcessStatus {
int32_t pid;
std::string name;
int32_t ppid;
int32_t uid;
};
struct ProcessCpuData {
int64_t utime;
int64_t stime;
int64_t cutime;
int64_t cstime;
};
struct BootData {
int64_t user;
int64_t nice;
int64_t system;
int64_t idle;
int64_t iowait;
int64_t irq;
int64_t softirq;
int64_t steal;
};
PssData g_pssData[] = { {1499}, {230} };
DiskioData g_diskioData[] = { {479, 577, 1973, 8092, 2574, 50, 91}, {7201784, 3168, 54150, 35, 22499328, 0, 0} };
ProcessStatus g_processStatus[] = { {11, "test", 2, 0}, {1872, "ibus-x11", 0, 1} };
ProcessCpuData g_processCpuData[] = { {60, 10, 20, 30}, {70, 10, 50, 30} };
BootData g_bootData = {24875428, 3952448, 11859815, 1193297105, 8980661, 0, 2607250, 0};
class ProcessDataPluginTest : public ::testing::Test {
public:
static void SetUpTestCase() {}
static void TearDownTestCase()
{
if (access(g_testPath.c_str(), F_OK) == 0) {
std::string str = "rm -rf " + g_testPath;
system(str.c_str());
}
}
};
string Getexepath()
{
char buf[PATH_MAX] = "";
std::string path = "/proc/self/exe";
size_t rslt = readlink(path.c_str(), buf, sizeof(buf));
if (rslt < 0 || (rslt >= sizeof(buf))) {
return "";
}
buf[rslt] = '\0';
for (int i = rslt; i >= 0; i--) {
if (buf[i] == '/') {
buf[i + 1] = '\0';
break;
}
}
return buf;
}
std::string GetFullPath(std::string path)
{
if (path.size() > 0 && path[0] != '/') {
return Getexepath() + path;
}
return path;
}
bool PluginCpuinfoStub(ProcessData& processData, ProcessConfig& protoConfig, bool unusualBuff)
{
CHECK_NOTNULL(processPlugin, false, "PluginCpuinfoStub fail");
// serialize
std::vector<uint8_t> configData(protoConfig.ByteSizeLong());
int ret = protoConfig.SerializeToArray(configData.data(), configData.size());
// start
ret = processPlugin->Start(configData.data(), configData.size());
if (ret < 0) {
return false;
}
// report
std::vector<uint8_t> bufferData(BUF_SIZE);
if (unusualBuff) { // buffer异常调整缓冲区长度为1测试异常情况
bufferData.resize(1, 0);
}
ret = processPlugin->Report(bufferData.data(), bufferData.size());
if (ret > 0) {
processData.ParseFromArray(bufferData.data(), ret);
return true;
}
return false;
}
void GetCpuData(std::vector<CpuData>& cpuDataVec, int64_t Hz)
{
int64_t bootTime = (g_bootData.user + g_bootData.nice + g_bootData.system + g_bootData.idle + g_bootData.iowait
+ g_bootData.irq + g_bootData.softirq + g_bootData.steal) * Hz;
for (int i = 0; i < PROCESS_NUM; i++) {
int cpu_time_ms = (g_processCpuData[i].utime + g_processCpuData[i].stime + g_processCpuData[i].cutime
+ g_processCpuData[i].cstime) * Hz;
double cpu_usage = static_cast<double>(cpu_time_ms) / bootTime * PERCENT;
cpuDataVec.push_back({cpu_usage, 1, cpu_time_ms});
}
cpuDataVec[1].thread_sum = THREAD_NUM;
}
/**
* @tc.name: process plugin
* @tc.desc: Test whether the path exists.
* @tc.type: FUNC
*/
HWTEST_F(ProcessDataPluginTest, TestPath, TestSize.Level1)
{
g_path = GetFullPath(DEFAULT_TEST_PATH);
g_testPath = g_path;
EXPECT_NE("", g_path);
}
/**
* @tc.name: process plugin
* @tc.desc: process plugin test for report process tree.
* @tc.type: FUNC
*/
HWTEST_F(ProcessDataPluginTest, TestPluginReportProcessTree, TestSize.Level1)
{
g_path = g_testPath + "/proc/";
processPlugin = std::make_shared<ProcessDataPlugin>();
processPlugin->SetPath(g_path);
ProcessData processData;
ProcessConfig processConfig;
processConfig.set_report_process_tree(true);
EXPECT_TRUE(PluginCpuinfoStub(processData, processConfig, false));
for (int i = 0; i < PROCESS_NUM && i < processData.processesinfo().size(); i++) {
ProcessInfo processesinfo = processData.processesinfo()[i];
EXPECT_EQ(processesinfo.pid(), g_processStatus[i].pid);
EXPECT_STREQ(processesinfo.name().c_str(), g_processStatus[i].name.c_str());
EXPECT_EQ(processesinfo.ppid(), g_processStatus[i].ppid);
EXPECT_EQ(processesinfo.uid(), g_processStatus[i].uid);
}
EXPECT_EQ(processPlugin->Stop(), 0);
}
/**
* @tc.name: process plugin
* @tc.desc: process plugin test for report cpu.
* @tc.type: FUNC
*/
HWTEST_F(ProcessDataPluginTest, TestPluginReportCpu, TestSize.Level1)
{
g_path = g_testPath + "/proc/";
processPlugin = std::make_shared<ProcessDataPlugin>();
processPlugin->SetPath(g_path);
ProcessData processData;
ProcessConfig processConfig;
processConfig.set_report_process_tree(true);
processConfig.set_report_cpu(true);
EXPECT_TRUE(PluginCpuinfoStub(processData, processConfig, false));
std::vector<CpuData> cpuDataVec;
int64_t Hz = processPlugin->GetUserHz();
GetCpuData(cpuDataVec, Hz);
for (int i = 0; i < PROCESS_NUM && i < processData.processesinfo().size(); i++) {
CpuInfo cpuInfo = processData.processesinfo()[i].cpuinfo();
EXPECT_FLOAT_EQ(cpuInfo.cpu_usage(), cpuDataVec[i].cpu_usage);
EXPECT_EQ(cpuInfo.thread_sum(), cpuDataVec[i].thread_sum);
EXPECT_EQ(cpuInfo.cpu_time_ms(), cpuDataVec[i].cpu_time_ms);
}
EXPECT_EQ(processPlugin->Stop(), 0);
}
/**
* @tc.name: process plugin
* @tc.desc: process plugin test for report diskio.
* @tc.type: FUNC
*/
HWTEST_F(ProcessDataPluginTest, TestPluginReportDiskio, TestSize.Level1)
{
g_path = g_testPath + "/proc/";
processPlugin = std::make_shared<ProcessDataPlugin>();
processPlugin->SetPath(g_path);
ProcessData processData;
ProcessConfig processConfig;
processConfig.set_report_process_tree(true);
processConfig.set_report_diskio(true);
EXPECT_TRUE(PluginCpuinfoStub(processData, processConfig, false));
for (int i = 0; i < PROCESS_NUM && i < processData.processesinfo().size(); i++) {
DiskioInfo diskinfo = processData.processesinfo()[i].diskinfo();
EXPECT_EQ(diskinfo.rchar(), g_diskioData[i].rchar);
EXPECT_EQ(diskinfo.wchar(), g_diskioData[i].wchar);
EXPECT_EQ(diskinfo.syscr(), g_diskioData[i].syscr);
EXPECT_EQ(diskinfo.syscw(), g_diskioData[i].syscw);
EXPECT_EQ(diskinfo.rbytes(), g_diskioData[i].rbytes);
EXPECT_EQ(diskinfo.wbytes(), g_diskioData[i].wbytes);
EXPECT_EQ(diskinfo.cancelled_wbytes(), g_diskioData[i].cancelled_wbytes);
}
EXPECT_EQ(processPlugin->Stop(), 0);
}
/**
* @tc.name: process plugin
* @tc.desc: process plugin test for report pss.
* @tc.type: FUNC
*/
HWTEST_F(ProcessDataPluginTest, TestPluginReportPss, TestSize.Level1)
{
g_path = g_testPath + "/proc/";
processPlugin = std::make_shared<ProcessDataPlugin>();
processPlugin->SetPath(g_path);
ProcessData processData;
ProcessConfig processConfig;
processConfig.set_report_process_tree(true);
processConfig.set_report_pss(true);
EXPECT_TRUE(PluginCpuinfoStub(processData, processConfig, false));
for (int i = 0; i < PROCESS_NUM && i < processData.processesinfo().size(); i++) {
PssInfo pssinfo = processData.processesinfo()[i].pssinfo();
EXPECT_EQ(pssinfo.pss_info(), g_pssData[i].pss_info);
}
EXPECT_EQ(processPlugin->Stop(), 0);
}
/**
* @tc.name: process plugin
* @tc.desc: process plugin test.
* @tc.type: FUNC
*/
HWTEST_F(ProcessDataPluginTest, TestPluginReportAll, TestSize.Level1)
{
g_path = g_testPath + "/proc/";
processPlugin = std::make_shared<ProcessDataPlugin>();
processPlugin->SetPath(g_path);
ProcessData processData;
ProcessConfig processConfig;
processConfig.set_report_process_tree(true);
processConfig.set_report_cpu(true);
processConfig.set_report_pss(true);
processConfig.set_report_diskio(true);
EXPECT_TRUE(PluginCpuinfoStub(processData, processConfig, false));
std::vector<CpuData> cpuDataVec;
int64_t Hz = processPlugin->GetUserHz();
GetCpuData(cpuDataVec, Hz);
for (int i = 0; i < PROCESS_NUM && i < processData.processesinfo().size(); i++) {
ProcessInfo processesinfo = processData.processesinfo()[i];
CpuInfo cpuInfo = processData.processesinfo()[i].cpuinfo();
DiskioInfo diskinfo = processData.processesinfo()[i].diskinfo();
PssInfo pssinfo = processData.processesinfo()[i].pssinfo();
EXPECT_EQ(processesinfo.pid(), g_processStatus[i].pid);
EXPECT_STREQ(processesinfo.name().c_str(), g_processStatus[i].name.c_str());
EXPECT_EQ(processesinfo.ppid(), g_processStatus[i].ppid);
EXPECT_EQ(processesinfo.uid(), g_processStatus[i].uid);
EXPECT_FLOAT_EQ(cpuInfo.cpu_usage(), cpuDataVec[i].cpu_usage);
EXPECT_EQ(cpuInfo.thread_sum(), cpuDataVec[i].thread_sum);
EXPECT_EQ(cpuInfo.cpu_time_ms(), cpuDataVec[i].cpu_time_ms);
EXPECT_EQ(diskinfo.rchar(), g_diskioData[i].rchar);
EXPECT_EQ(diskinfo.wchar(), g_diskioData[i].wchar);
EXPECT_EQ(diskinfo.syscr(), g_diskioData[i].syscr);
EXPECT_EQ(diskinfo.syscw(), g_diskioData[i].syscw);
EXPECT_EQ(diskinfo.rbytes(), g_diskioData[i].rbytes);
EXPECT_EQ(diskinfo.wbytes(), g_diskioData[i].wbytes);
EXPECT_EQ(diskinfo.cancelled_wbytes(), g_diskioData[i].cancelled_wbytes);
EXPECT_EQ(pssinfo.pss_info(), g_pssData[i].pss_info);
}
EXPECT_EQ(processPlugin->Stop(), 0);
}
/**
* @tc.name: process plugin
* @tc.desc: process plugin test for unusual path.
* @tc.type: FUNC
*/
HWTEST_F(ProcessDataPluginTest, TestPluginUnusualPath, TestSize.Level1)
{
processPlugin = std::make_shared<ProcessDataPlugin>();
processPlugin->SetPath("123");
ProcessData processData;
ProcessConfig processConfig;
processConfig.set_report_process_tree(true);
EXPECT_FALSE(PluginCpuinfoStub(processData, processConfig, false));
}
/**
* @tc.name: process plugin
* @tc.desc: process plugin test for buffer exception.
* @tc.type: FUNC
*/
HWTEST_F(ProcessDataPluginTest, TestPluginBufferException, TestSize.Level1)
{
g_path = g_testPath + "/proc/";
processPlugin = std::make_shared<ProcessDataPlugin>();
processPlugin->SetPath(g_path);
// 缓冲区异常
ProcessData processData;
ProcessConfig processConfig;
processConfig.set_report_process_tree(true);
EXPECT_FALSE(PluginCpuinfoStub(processData, processConfig, true));
}
/**
* @tc.name: process plugin
* @tc.desc: process plugin registration test.
* @tc.type: FUNC
*/
HWTEST_F(ProcessDataPluginTest, TestPluginRegister, TestSize.Level1)
{
void* handle = dlopen(SO_PATH.c_str(), RTLD_LAZY);
ASSERT_NE(handle, nullptr);
PluginModuleStruct* processPlugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule");
ASSERT_NE(processPlugin, nullptr);
EXPECT_STREQ(processPlugin->name, "process-plugin");
EXPECT_EQ(processPlugin->resultBufferSizeHint, BUF_SIZE);
// Serialize config
ProcessConfig processConfig;
processConfig.set_report_process_tree(true);
int configLength = processConfig.ByteSizeLong();
ASSERT_GT(configLength, 0);
std::vector<uint8_t> configBuffer(configLength);
EXPECT_TRUE(processConfig.SerializeToArray(configBuffer.data(), configLength));
// run plugin
std::vector<uint8_t> dataBuffer(processPlugin->resultBufferSizeHint);
EXPECT_EQ(processPlugin->callbacks->onPluginSessionStart(configBuffer.data(), configLength), RET_SUCC);
int len = processPlugin->callbacks->onPluginReportResult(dataBuffer.data(), processPlugin->resultBufferSizeHint);
ASSERT_GT(len, 0);
EXPECT_EQ(processPlugin->callbacks->onPluginSessionStop(), RET_SUCC);
// 反序列化失败导致的start失败
EXPECT_EQ(processPlugin->callbacks->onPluginSessionStart(configBuffer.data(), configLength+1), RET_FAIL);
}
} // namespace

View File

@ -19,4 +19,7 @@ option optimize_for = LITE_RUNTIME;
message ProcessConfig {
// set true to report process list
bool report_process_tree = 1;
bool report_cpu = 2;
bool report_diskio = 3;
bool report_pss = 4;
}

View File

@ -16,9 +16,36 @@ syntax = "proto3";
option java_package = "ohos.devtools.datasources.transport.grpc.service";
option optimize_for = LITE_RUNTIME;
message DiskioInfo {
// read /proc/pid/io
uint64 rchar = 1;
uint64 wchar = 2;
uint64 syscr = 3;
uint64 syscw = 4;
uint64 rbytes = 5;
uint64 wbytes = 6;
uint64 cancelled_wbytes = 7;
}
message PssInfo {
// read /proc/pid/smaps_rollup
int32 pss_info = 1;
}
message CpuInfo {
double cpu_usage = 1;
int32 thread_sum = 2;
uint64 cpu_time_ms = 3;
}
message ProcessInfo {
int32 pid = 1;
string name = 2;
int32 ppid = 3;
int32 uid = 4;
CpuInfo cpuinfo = 5;
PssInfo pssinfo = 6;
DiskioInfo diskinfo = 7;
}
message ProcessData {