1 /*
2 * Copyright (c) 2023 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
16 #include "dfx_test_util.h"
17
18 #include <fstream>
19 #include <iostream>
20 #include <sstream>
21 #include <unistd.h>
22
23 #include "dfx_define.h"
24 #include <directory_ex.h>
25 #include "file_util.h"
26 #include <string_ex.h>
27
28 namespace OHOS {
29 namespace HiviewDFX {
30 namespace {
31 const int BUF_LEN = 128;
32 }
33
ExecuteCommands(const std::string & cmds)34 std::string ExecuteCommands(const std::string& cmds)
35 {
36 if (cmds.empty()) {
37 return "";
38 }
39 FILE *procFileInfo = nullptr;
40 std::string cmdLog = "";
41 procFileInfo = popen(cmds.c_str(), "r");
42 if (procFileInfo == nullptr) {
43 perror("popen execute failed\n");
44 return cmdLog;
45 }
46 char res[BUF_LEN] = { '\0' };
47 while (fgets(res, sizeof(res), procFileInfo) != nullptr) {
48 cmdLog += res;
49 }
50 pclose(procFileInfo);
51 return cmdLog;
52 }
53
ExecuteCommands(const std::string & cmds,std::vector<std::string> & ress)54 bool ExecuteCommands(const std::string& cmds, std::vector<std::string>& ress)
55 {
56 if (cmds.empty()) {
57 return false;
58 }
59
60 ress.clear();
61 FILE *fp = nullptr;
62 fp = popen(cmds.c_str(), "r");
63 if (fp == nullptr) {
64 perror("popen execute failed\n");
65 return false;
66 }
67
68 char res[BUF_LEN] = { '\0' };
69 while (fgets(res, sizeof(res), fp) != nullptr) {
70 ress.push_back(std::string(res));
71 }
72 pclose(fp);
73 return true;
74 }
75
GetProcessPid(const std::string & processName)76 int GetProcessPid(const std::string& processName)
77 {
78 std::string cmd = "pidof " + processName;
79 std::string pidStr = ExecuteCommands(cmd);
80 int32_t pid = 0;
81 std::stringstream pidStream(pidStr);
82 pidStream >> pid;
83 printf("the pid of process(%s) is %s \n", processName.c_str(), pidStr.c_str());
84 return pid;
85 }
86
LaunchTestHap(const std::string & abilityName,const std::string & bundleName)87 int LaunchTestHap(const std::string& abilityName, const std::string& bundleName)
88 {
89 std::string launchCmd = "/system/bin/aa start -a " + abilityName + " -b " + bundleName;
90 (void)ExecuteCommands(launchCmd);
91 sleep(2); // 2 : sleep 2s
92 return GetProcessPid(bundleName);
93 }
94
StopTestHap(const std::string & bundleName)95 void StopTestHap(const std::string& bundleName)
96 {
97 std::string stopCmd = "/system/bin/aa force-stop " + bundleName;
98 (void)ExecuteCommands(stopCmd);
99 }
100
InstallTestHap(const std::string & hapName)101 void InstallTestHap(const std::string& hapName)
102 {
103 std::string installCmd = "bm install -p " + hapName;
104 (void)ExecuteCommands(installCmd);
105 }
106
UninstallTestHap(const std::string & bundleName)107 void UninstallTestHap(const std::string& bundleName)
108 {
109 std::string uninstallCmd = "bm uninstall -n " + bundleName;
110 (void)ExecuteCommands(uninstallCmd);
111 }
112
CountLines(const std::string & fileName)113 int CountLines(const std::string& fileName)
114 {
115 std::ifstream readFile;
116 readFile.open(fileName.c_str(), std::ios::in);
117 if (readFile.fail()) {
118 return 0;
119 } else {
120 int n = 0;
121 std::string tmpuseValue;
122 while (getline(readFile, tmpuseValue, '\n')) {
123 n++;
124 }
125 readFile.close();
126 return n;
127 }
128 }
129
CheckProcessComm(int pid,const std::string & name)130 bool CheckProcessComm(int pid, const std::string& name)
131 {
132 std::string cmd = "cat /proc/" + std::to_string(pid) + "/comm";
133 std::string comm = ExecuteCommands(cmd);
134 size_t pos = comm.find('\n');
135 if (pos != std::string::npos) {
136 comm.erase(pos, 1);
137 }
138 if (!strcmp(comm.c_str(), name.c_str())) {
139 return true;
140 }
141 return false;
142 }
143
CheckKeyWords(const std::string & filePath,std::string * keywords,int length,int minRegIdx)144 int CheckKeyWords(const std::string& filePath, std::string *keywords, int length, int minRegIdx)
145 {
146 std::ifstream file;
147 file.open(filePath.c_str(), std::ios::in);
148 long lines = CountLines(filePath);
149 std::vector<std::string> t(lines * 4); // 4 : max string blocks of one line
150 int i = 0;
151 int j = 0;
152 std::string::size_type idx;
153 int count = 0;
154 int maxRegIdx = minRegIdx + REGISTERS_NUM + 1;
155 while (!file.eof()) {
156 file >> t.at(i);
157 idx = t.at(i).find(keywords[j]);
158 if (idx != std::string::npos) {
159 if (minRegIdx != -1 && j > minRegIdx && // -1 : do not check register value
160 j < maxRegIdx && t.at(i).size() < (REGISTER_FORMAT_LENGTH + 3)) { // 3 : register label length
161 count--;
162 }
163 count++;
164 j++;
165 if (j == length) {
166 break;
167 }
168 continue;
169 }
170 i++;
171 }
172 file.close();
173 std::cout << "Matched keywords count: " << count << std::endl;
174 if (j < length) {
175 std::cout << "Not found keyword: " << keywords[j] << std::endl;
176 }
177 return count;
178 }
179
CheckContent(const std::string & content,const std::string & keyContent,bool checkExist)180 bool CheckContent(const std::string& content, const std::string& keyContent, bool checkExist)
181 {
182 bool findKeyContent = false;
183 if (content.find(keyContent) != std::string::npos) {
184 findKeyContent = true;
185 }
186
187 if (checkExist && !findKeyContent) {
188 printf("Failed to find: %s in %s\n", keyContent.c_str(), content.c_str());
189 return false;
190 }
191
192 if (!checkExist && findKeyContent) {
193 printf("Find: %s in %s\n", keyContent.c_str(), content.c_str());
194 return false;
195 }
196 return true;
197 }
198
GetKeywordsNum(const std::string & msg,std::string * keywords,int length)199 int GetKeywordsNum(const std::string& msg, std::string *keywords, int length)
200 {
201 int count = 0;
202 std::string::size_type idx;
203 for (int i = 0; i < length; i++) {
204 idx = msg.find(keywords[i]);
205 if (idx != std::string::npos) {
206 count++;
207 }
208 }
209 return count;
210 }
211
GetCppCrashFileName(const pid_t pid)212 std::string GetCppCrashFileName(const pid_t pid)
213 {
214 std::string filePath = "";
215 if (pid <= 0) {
216 return filePath;
217 }
218 std::string fileNamePrefix = "cppcrash-" + std::to_string(pid);
219 std::vector<std::string> files;
220 OHOS::GetDirFiles("/data/log/faultlog/temp/", files);
221 for (const auto& file : files) {
222 if (file.find(fileNamePrefix) != std::string::npos) {
223 filePath = file;
224 break;
225 }
226 }
227 return filePath;
228 }
229
GetSelfMemoryCount()230 uint64_t GetSelfMemoryCount()
231 {
232 std::string path = "/proc/self/smaps_rollup";
233 std::string content;
234 if (!OHOS::HiviewDFX::LoadStringFromFile(path, content)) {
235 printf("Failed to load path content: %s\n", path.c_str());
236 return 0;
237 }
238
239 std::vector<std::string> result;
240 OHOS::SplitStr(content, "\n", result);
241 auto iter = std::find_if(result.begin(), result.end(),
242 [] (const std::string& str) {
243 return str.find("Pss:") != std::string::npos;
244 });
245 if (iter == result.end()) {
246 perror("Failed to find Pss.\n");
247 return 0;
248 }
249
250 std::string pss = *iter;
251 uint64_t retVal = 0;
252 for (size_t i = 0; i < pss.size(); i++) {
253 if (isdigit(pss[i])) {
254 retVal = atoi(&pss[i]);
255 break;
256 }
257 }
258 return retVal;
259 }
260
GetSelfMapsCount()261 uint32_t GetSelfMapsCount()
262 {
263 std::string path = "/proc/self/maps";
264 std::string content;
265 if (!OHOS::HiviewDFX::LoadStringFromFile(path, content)) {
266 printf("Failed to load path content: %s\n", path.c_str());
267 return 0;
268 }
269
270 std::vector<std::string> result;
271 OHOS::SplitStr(content, "\n", result);
272 return result.size();
273 }
274
GetSelfFdCount()275 uint32_t GetSelfFdCount()
276 {
277 std::string path = "/proc/self/fd";
278 std::vector<std::string> content;
279 OHOS::GetDirFiles(path, content);
280 return content.size();
281 }
282 } // namespace HiviewDFX
283 } // namespace OHOS