diff --git a/OAT.xml b/OAT.xml
index 55875b61b..493fb475d 100644
--- a/OAT.xml
+++ b/OAT.xml
@@ -62,6 +62,7 @@ Note:If the text contains special characters, please escape them according to th
+
@@ -86,6 +87,7 @@ Note:If the text contains special characters, please escape them according to th
+
diff --git a/device/BUILD.gn b/device/BUILD.gn
index 2f3239cc7..15d25df50 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -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",
diff --git a/device/ohos_test.xml b/device/ohos_test.xml
index bd26ff004..8b5863378 100644
--- a/device/ohos_test.xml
+++ b/device/ohos_test.xml
@@ -117,10 +117,23 @@
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/device/plugins/process_plugin/include/process_data_plugin.h b/device/plugins/process_plugin/include/process_data_plugin.h
index 588c26b66..3248baa83 100644
--- a/device/plugins/process_plugin/include/process_data_plugin.h
+++ b/device/plugins/process_plugin/include/process_data_plugin.h
@@ -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 buffer_;
-
- std::unordered_map> pidFds_;
- std::vector 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 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 buffer_;
+ std::vector pids_;
+ std::string path_;
+ int32_t err_;
+ std::unordered_map cpuTime_ = {};
+ std::unordered_map bootTime_ = {};
};
#endif
diff --git a/device/plugins/process_plugin/src/process_data_plugin.cpp b/device/plugins/process_plugin/src/process_data_plugin.cpp
index 84325706f..5b830e956 100644
--- a/device/plugins/process_plugin/src/process_data_plugin.cpp
+++ b/device/plugins/process_plugin/src/process_data_plugin.cpp
@@ -15,6 +15,8 @@
#include "process_data_plugin.h"
#include
+#include
+#include
#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("/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(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(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(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 cpuUsageVec;
+ std::vector 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(cpuTime) / (bootTime);
+ } else {
+ usage = static_cast(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(line.c_str());
+ constexpr uint32_t cntVec = 8;
+
+ std::vector 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(line.c_str());
+ int i = 0;
+ constexpr uint32_t cntVec = 4;
+
+ while (FindFirstSpace(&pTmp)) {
+ pTmp++;
+ if (++i >= STAT_COUNT) {
+ break;
+ }
+ }
+ std::vector 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(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(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;
}
diff --git a/device/plugins/process_plugin/test/BUILD.gn b/device/plugins/process_plugin/test/BUILD.gn
new file mode 100755
index 000000000..e205b9e3c
--- /dev/null
+++ b/device/plugins/process_plugin/test/BUILD.gn
@@ -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" ]
+}
diff --git a/device/plugins/process_plugin/test/resources/proc/11/cmdline b/device/plugins/process_plugin/test/resources/proc/11/cmdline
new file mode 100755
index 000000000..30d74d258
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/11/cmdline
@@ -0,0 +1 @@
+test
\ No newline at end of file
diff --git a/device/plugins/process_plugin/test/resources/proc/11/io b/device/plugins/process_plugin/test/resources/proc/11/io
new file mode 100755
index 000000000..0d9bbdbea
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/11/io
@@ -0,0 +1,7 @@
+rchar: 479
+wchar: 577
+syscr: 1973
+syscw: 8092
+read_bytes: 2574
+write_bytes: 50
+cancelled_write_bytes: 91
diff --git a/device/plugins/process_plugin/test/resources/proc/11/smaps_rollup b/device/plugins/process_plugin/test/resources/proc/11/smaps_rollup
new file mode 100755
index 000000000..e0ce29ba3
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/11/smaps_rollup
@@ -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
diff --git a/device/plugins/process_plugin/test/resources/proc/11/stat b/device/plugins/process_plugin/test/resources/proc/11/stat
new file mode 100755
index 000000000..efe5ad84c
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/11/stat
@@ -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
diff --git a/device/plugins/process_plugin/test/resources/proc/11/status b/device/plugins/process_plugin/test/resources/proc/11/status
new file mode 100755
index 000000000..f5ea4336c
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/11/status
@@ -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
diff --git a/device/plugins/process_plugin/test/resources/proc/11/task/11/cmdline b/device/plugins/process_plugin/test/resources/proc/11/task/11/cmdline
new file mode 100755
index 000000000..30d74d258
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/11/task/11/cmdline
@@ -0,0 +1 @@
+test
\ No newline at end of file
diff --git a/device/plugins/process_plugin/test/resources/proc/1872/cmdline b/device/plugins/process_plugin/test/resources/proc/1872/cmdline
new file mode 100755
index 000000000..4b7fac640
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/1872/cmdline
@@ -0,0 +1 @@
+ibus-x11
\ No newline at end of file
diff --git a/device/plugins/process_plugin/test/resources/proc/1872/io b/device/plugins/process_plugin/test/resources/proc/1872/io
new file mode 100755
index 000000000..7af4818a4
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/1872/io
@@ -0,0 +1,7 @@
+rchar: 7201784
+wchar: 3168
+syscr: 54150
+syscw: 35
+read_bytes: 22499328
+write_bytes: 0
+cancelled_write_bytes: 0
diff --git a/device/plugins/process_plugin/test/resources/proc/1872/smaps_rollup b/device/plugins/process_plugin/test/resources/proc/1872/smaps_rollup
new file mode 100755
index 000000000..e665b4798
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/1872/smaps_rollup
@@ -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
diff --git a/device/plugins/process_plugin/test/resources/proc/1872/stat b/device/plugins/process_plugin/test/resources/proc/1872/stat
new file mode 100755
index 000000000..6276b51ec
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/1872/stat
@@ -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
diff --git a/device/plugins/process_plugin/test/resources/proc/1872/status b/device/plugins/process_plugin/test/resources/proc/1872/status
new file mode 100755
index 000000000..1214e8170
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/1872/status
@@ -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
diff --git a/device/plugins/process_plugin/test/resources/proc/1872/task/1872/cmdline b/device/plugins/process_plugin/test/resources/proc/1872/task/1872/cmdline
new file mode 100755
index 000000000..4b7fac640
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/1872/task/1872/cmdline
@@ -0,0 +1 @@
+ibus-x11
\ No newline at end of file
diff --git a/device/plugins/process_plugin/test/resources/proc/1872/task/1873/cmdline b/device/plugins/process_plugin/test/resources/proc/1872/task/1873/cmdline
new file mode 100755
index 000000000..77ee75962
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/1872/task/1873/cmdline
@@ -0,0 +1 @@
+ibus-x1:disk$0
\ No newline at end of file
diff --git a/device/plugins/process_plugin/test/resources/proc/1872/task/1965/cmdline b/device/plugins/process_plugin/test/resources/proc/1872/task/1965/cmdline
new file mode 100755
index 000000000..9dc8af102
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/1872/task/1965/cmdline
@@ -0,0 +1 @@
+ibus-x1:disk$1
\ No newline at end of file
diff --git a/device/plugins/process_plugin/test/resources/proc/stat b/device/plugins/process_plugin/test/resources/proc/stat
new file mode 100755
index 000000000..d516b7d16
--- /dev/null
+++ b/device/plugins/process_plugin/test/resources/proc/stat
@@ -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
diff --git a/device/plugins/process_plugin/test/unittest/process_plugin_unittest.cpp b/device/plugins/process_plugin/test/unittest/process_plugin_unittest.cpp
new file mode 100755
index 000000000..3fc06da27
--- /dev/null
+++ b/device/plugins/process_plugin/test/unittest/process_plugin_unittest.cpp
@@ -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
+#include
+#include
+#include
+
+#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 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 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 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& 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(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();
+ 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();
+ 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 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();
+ 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();
+ 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();
+ 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 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();
+ 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();
+ 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 configBuffer(configLength);
+ EXPECT_TRUE(processConfig.SerializeToArray(configBuffer.data(), configLength));
+
+ // run plugin
+ std::vector 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
diff --git a/protos/types/plugins/process_data/process_plugin_config.proto b/protos/types/plugins/process_data/process_plugin_config.proto
index ecb838927..75b20efc4 100644
--- a/protos/types/plugins/process_data/process_plugin_config.proto
+++ b/protos/types/plugins/process_data/process_plugin_config.proto
@@ -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;
}
diff --git a/protos/types/plugins/process_data/process_plugin_result.proto b/protos/types/plugins/process_data/process_plugin_result.proto
index 53f586b5f..8f790ed02 100644
--- a/protos/types/plugins/process_data/process_plugin_result.proto
+++ b/protos/types/plugins/process_data/process_plugin_result.proto
@@ -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 {