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 28namespace OHOS { 29namespace HiviewDFX { 30namespace { 31const int BUF_LEN = 128; 32} 33 34std::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 54bool 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 76int 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 87int 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 95void StopTestHap(const std::string& bundleName) 96{ 97 std::string stopCmd = "/system/bin/aa force-stop " + bundleName; 98 (void)ExecuteCommands(stopCmd); 99} 100 101void InstallTestHap(const std::string& hapName) 102{ 103 std::string installCmd = "bm install -p " + hapName; 104 (void)ExecuteCommands(installCmd); 105} 106 107void UninstallTestHap(const std::string& bundleName) 108{ 109 std::string uninstallCmd = "bm uninstall -n " + bundleName; 110 (void)ExecuteCommands(uninstallCmd); 111} 112 113int 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 130bool 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 144int 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 180bool 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 199int 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 212std::string GetCppCrashFileName(const pid_t pid, const std::string& tempPath) 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(tempPath, 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 230uint64_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 261uint32_t GetSelfMapsCount() 262{ 263 std::string path = std::string(PROC_SELF_MAPS_PATH); 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 275uint32_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 283void CheckResourceUsage(uint32_t fdCount, uint32_t mapsCount, uint64_t memCount) 284{ 285 // check memory/fd/maps 286 auto curFdCount = GetSelfFdCount(); 287 printf("AfterTest Fd New: %u\n", curFdCount); 288 printf("Fd Old: %u\n", fdCount); 289 290 auto curMapsCount = GetSelfMapsCount(); 291 printf("AfterTest Maps New: %u\n", curMapsCount); 292 printf("Maps Old: %u\n", mapsCount); 293 294 auto curMemSize = GetSelfMemoryCount(); 295 printf("AfterTest Memory New: %lu\n", static_cast<unsigned long>(curMemSize)); 296 printf("Memory Old: %lu\n", static_cast<unsigned long>(memCount)); 297} 298} // namespace HiviewDFX 299} // namespace OHOS