1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. 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 <array> 17 #include <dlfcn.h> 18 #include <fcntl.h> 19 #include <hwext/gtest-ext.h> 20 #include <hwext/gtest-tag.h> 21 #include <sys/stat.h> 22 #include <sys/syscall.h> 23 #include <unistd.h> 24 25 #include "logging.h" 26 #include "openssl/sha.h" 27 28 using namespace testing::ext; 29 30 #define HHB(v) (((v) & 0xF0) >> 4) 31 #define LHB(v) ((v) & 0x0F) 32 33 namespace { 34 #if defined(__LP64__) 35 const std::string DEFAULT_SO_PATH("/system/lib64/"); 36 #else 37 const std::string DEFAULT_SO_PATH("/system/lib/"); 38 #endif 39 const std::string DEFAULT_HIPROFILERD_PATH("/system/bin/hiprofilerd"); 40 const std::string DEFAULT_HIPROFILER_PLUGINS_PATH("/system/bin/hiprofiler_plugins"); 41 const std::string DEFAULT_HIPROFILERD_NAME("hiprofilerd"); 42 const std::string DEFAULT_HIPROFILER_PLUGINS_NAME("hiprofiler_plugins"); 43 44 const std::string DEFAULT_HIPROFILER_CMD_PATH("/system/bin/hiprofiler_cmd"); 45 const std::string FTRACE_PLUGIN_PATH("/data/local/tmp/libftrace_plugin.z.so"); 46 const std::string HIPERF_PLUGIN_PATH("/data/local/tmp/libhiperfplugin.z.so"); 47 std::string DEFAULT_PATH("/data/local/tmp/"); 48 constexpr uint32_t READ_BUFFER_SIZE = 1024; 49 constexpr int SLEEP_TIME = 3; 50 constexpr int FILE_READ_CHUNK_SIZE = 4096; 51 constexpr char HEX_CHARS[] = "0123456789abcdef"; 52 constexpr int LINE_SIZE = 1000; 53 54 55 class HiprofilerCmdTest : public ::testing::Test { 56 public: SetUpTestCase()57 static void SetUpTestCase() {} TearDownTestCase()58 static void TearDownTestCase() {} 59 StartServerStub(std::string name)60 void StartServerStub(std::string name) 61 { 62 if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) { 63 return; 64 } 65 int processNum = fork(); 66 if (processNum == 0) { 67 if (DEFAULT_HIPROFILERD_PATH == name) { 68 // start running hiprofilerd 69 execl(name.c_str(), nullptr, nullptr); 70 } else if (DEFAULT_HIPROFILER_PLUGINS_PATH == name) { 71 // start running hiprofiler_plugins 72 execl(name.c_str(), DEFAULT_PATH.c_str(), nullptr); 73 } 74 _exit(1); 75 } else if (DEFAULT_HIPROFILERD_PATH == name) { 76 hiprofilerdPid_ = processNum; 77 } else if (DEFAULT_HIPROFILER_PLUGINS_PATH == name) { 78 hiprofilerPluginsPid_ = processNum; 79 } 80 } 81 StopProcessStub(int processNum)82 void StopProcessStub(int processNum) 83 { 84 std::string stopCmd = "kill " + std::to_string(processNum); 85 std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(stopCmd.c_str(), "r"), pclose); 86 sleep(SLEEP_TIME); // wait process exit 87 } 88 RunCommand(const std::string & cmd,std::string & content)89 bool RunCommand(const std::string& cmd, std::string& content) 90 { 91 std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose); 92 CHECK_TRUE(pipe, false, "RunCommand: create popen FAILED!"); 93 std::array<char, READ_BUFFER_SIZE> buffer; 94 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { 95 content += buffer.data(); 96 } 97 return true; 98 } 99 ComputeFileSha256(const std::string & path)100 std::string ComputeFileSha256(const std::string& path) 101 { 102 uint8_t out[SHA256_DIGEST_LENGTH]; 103 uint8_t buffer[FILE_READ_CHUNK_SIZE]; 104 char realPath[PATH_MAX + 1] = {0}; 105 106 SHA256_CTX sha; 107 SHA256_Init(&sha); 108 109 size_t nbytes = 0; 110 111 if ((strlen(path.c_str()) >= PATH_MAX) || (realpath(path.c_str(), realPath) == nullptr)) { 112 PROFILER_LOG_ERROR(LOG_CORE, "%s:path is invalid: %s, errno=%d", __func__, path.c_str(), errno); 113 return ""; 114 } 115 FILE* file = fopen(realPath, "rb"); 116 if (file == nullptr) { 117 return ""; 118 } 119 120 std::unique_ptr<FILE, decltype(fclose)*> fptr(file, fclose); 121 if (fptr == nullptr) { 122 return ""; 123 } 124 125 while ((nbytes = fread(buffer, 1, sizeof(buffer), fptr.get())) > 0) { 126 SHA256_Update(&sha, buffer, nbytes); 127 } 128 SHA256_Final(out, &sha); 129 130 std::string result; 131 result.reserve(SHA256_DIGEST_LENGTH + SHA256_DIGEST_LENGTH); 132 for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) { 133 result.push_back(HEX_CHARS[HHB(out[i])]); 134 result.push_back(HEX_CHARS[LHB(out[i])]); 135 } 136 137 PROFILER_LOG_DEBUG(LOG_CORE, "%s:%s-(%s)", __func__, path.c_str(), result.c_str()); 138 return result; 139 } 140 CreateConfigFile(const std::string configFile)141 void CreateConfigFile(const std::string configFile) 142 { 143 // 构建config文件 144 std::string configStr = 145 "request_id: 26\n" 146 "session_config {\n" 147 " buffers {\n" 148 " pages: 1000\n" 149 " }\n" 150 " result_file: \"/data/local/tmp/hiprofiler_data.htrace\"\n" 151 " sample_duration: 10000\n" 152 "}\n" 153 "plugin_configs {\n" 154 " plugin_name: \"ftrace-plugin\"\n" 155 " sample_interval: 2000\n" 156 " config_data: {\n" 157 " ftrace_events: \"sched/sched_switch\"\n" 158 " ftrace_events: \"sched/sched_wakeup\"\n" 159 " ftrace_events: \"sched/sched_wakeup_new\"\n" 160 " ftrace_events: \"sched/sched_waking\"\n" 161 " ftrace_events: \"sched/sched_process_exit\"\n" 162 " ftrace_events: \"sched/sched_process_free\"\n" 163 " buffer_size_kb: 51200\n" 164 " flush_interval_ms: 1000\n" 165 " flush_threshold_kb: 4096\n" 166 " parse_ksyms: true\n" 167 " clock: \"mono\"\n" 168 " trace_period_ms: 200\n" 169 " debug_on: false\n" 170 " }\n" 171 "}\n"; 172 173 // 根据构建的config写文件 174 FILE* writeFp = fopen(configFile.c_str(), "w"); 175 if (writeFp == nullptr) { 176 const int bufSize = 256; 177 char buf[bufSize] = { 0 }; 178 strerror_r(errno, buf, bufSize); 179 PROFILER_LOG_ERROR(LOG_CORE, "CreateConfigFile: fopen() error = %s", buf); 180 return; 181 } 182 183 size_t len = fwrite(const_cast<char*>(configStr.c_str()), 1, configStr.length(), writeFp); 184 if (len < 0) { 185 const int bufSize = 256; 186 char buf[bufSize] = { 0 }; 187 strerror_r(errno, buf, bufSize); 188 PROFILER_LOG_ERROR(LOG_CORE, "CreateConfigFile: fwrite() error = %s", buf); 189 if (fclose(writeFp) != 0) { 190 PROFILER_LOG_ERROR(LOG_CORE, "fclose() error"); 191 } 192 return; 193 } 194 195 int ret = fflush(writeFp); 196 if (ret == EOF) { 197 const int bufSize = 256; 198 char buf[bufSize] = { 0 }; 199 strerror_r(errno, buf, bufSize); 200 PROFILER_LOG_ERROR(LOG_CORE, "CreateConfigFile: fflush() error = %s", buf); 201 if (fclose(writeFp) != 0) { 202 PROFILER_LOG_ERROR(LOG_CORE, "fclose() error"); 203 } 204 return; 205 } 206 207 fsync(fileno(writeFp)); 208 ret = fclose(writeFp); 209 if (ret != 0) { 210 const int bufSize = 256; 211 char buf[bufSize] = { 0 }; 212 strerror_r(errno, buf, bufSize); 213 PROFILER_LOG_ERROR(LOG_CORE, "CreateConfigFile: fclose() error = %s", buf); 214 return; 215 } 216 } 217 CreateCommand(const std::string & outFile,int time) const218 std::string CreateCommand(const std::string &outFile, int time) const 219 { 220 std::string cmdStr = 221 "hiprofiler_cmd \\\n" 222 "-c - \\\n"; 223 cmdStr += "-o " + outFile + " \\\n"; 224 cmdStr += "-t " + std::to_string(time) + " \\\n"; 225 cmdStr += "-k \\\n" 226 "<<CONFIG\n" 227 "request_id: 1\n" 228 "session_config {\n" 229 " buffers {\n" 230 " pages: 1000\n" 231 " }\n" 232 " result_file: \"/data/local/tmp/hiprofiler_data.htrace\"\n" 233 " sample_duration: 1000\n" 234 "}\n" 235 "plugin_configs {\n" 236 " plugin_name: \"ftrace-plugin\"\n" 237 " sample_interval: 1000\n" 238 " is_protobuf_serialize: true\n" 239 " config_data {\n" 240 " ftrace_events: \"sched/sched_switch\"\n" 241 " ftrace_events: \"sched/sched_wakeup\"\n" 242 " ftrace_events: \"sched/sched_wakeup_new\"\n" 243 " ftrace_events: \"sched/sched_waking\"\n" 244 " ftrace_events: \"sched/sched_process_exit\"\n" 245 " ftrace_events: \"sched/sched_process_free\"\n" 246 " hitrace_categories: \"ability\"\n" 247 " hitrace_categories: \"ace\"\n" 248 " buffer_size_kb: 51200\n" 249 " flush_interval_ms: 1000\n" 250 " flush_threshold_kb: 4096\n" 251 " parse_ksyms: true\n" 252 " clock: \"mono\"\n" 253 " trace_period_ms: 200\n" 254 " debug_on: false\n" 255 " }\n" 256 "}\n" 257 "CONFIG\n"; 258 return cmdStr; 259 } 260 CreateHiperfCommand(const std::string & outFile,int time) const261 std::string CreateHiperfCommand(const std::string &outFile, int time) const 262 { 263 std::string cmdStr = 264 "hiprofiler_cmd \\\n" 265 "-c - \\\n"; 266 cmdStr += "-o " + outFile + " \\\n"; 267 cmdStr += "-t " + std::to_string(time) + " \\\n"; 268 cmdStr += "-k \\\n" 269 "<<CONFIG\n" 270 "request_id: 1\n" 271 "session_config {\n" 272 " buffers {\n" 273 " pages: 1000\n" 274 " }\n" 275 " result_file: \"/data/local/tmp/hiprofiler_data.htrace\"\n" 276 " sample_duration: 1000\n" 277 "}\n" 278 "plugin_configs {\n" 279 " plugin_name: \"hiperf-plugin\"\n" 280 " sample_interval: 1000\n" 281 " is_protobuf_serialize: true\n" 282 " config_data {\n" 283 " is_root: false\n" 284 " outfile_name: \"/data/local/tmp/perf.data\"\n" 285 " record_args: \"-f 1000 -a --call-stack dwarf\"\n" 286 " }\n" 287 "}\n" 288 "CONFIG\n"; 289 return cmdStr; 290 } 291 CreateEncoderCommand(const std::string & outFile,int time) const292 std::string CreateEncoderCommand(const std::string &outFile, int time) const 293 { 294 std::string cmdStr = 295 "hiprofiler_cmd \\\n" 296 "-c - \\\n"; 297 cmdStr += "-k \\\n"; 298 cmdStr += "-o " + outFile + " \\\n"; 299 cmdStr += "-t " + std::to_string(time) + " \\\n" 300 "<<CONFIG\n" 301 "request_id: 1\n" 302 "session_config {\n" 303 " buffers {\n" 304 " pages: 1000\n" 305 " }\n" 306 " result_file: \"/data/local/tmp/hiprofiler_data.htrace\"\n" 307 " sample_duration: 3000\n" 308 "}\n" 309 "plugin_configs {\n" 310 " plugin_name: \"ftrace-plugin\"\n" 311 " sample_interval: 1000\n" 312 " config_data {\n" 313 " ftrace_events: \"sched/sched_switch\"\n" 314 " ftrace_events: \"sched/sched_wakeup\"\n" 315 " ftrace_events: \"sched/sched_wakeup_new\"\n" 316 " ftrace_events: \"sched/sched_waking\"\n" 317 " ftrace_events: \"sched/sched_process_exit\"\n" 318 " ftrace_events: \"sched/sched_process_free\"\n" 319 " hitrace_categories: \"ability\"\n" 320 " hitrace_categories: \"ace\"\n" 321 " buffer_size_kb: 51200\n" 322 " flush_interval_ms: 1000\n" 323 " flush_threshold_kb: 4096\n" 324 " parse_ksyms: true\n" 325 " clock: \"mono\"\n" 326 " trace_period_ms: 200\n" 327 " debug_on: false\n" 328 " }\n" 329 "}\n" 330 "CONFIG\n"; 331 return cmdStr; 332 } 333 CreateSplitHtraceCommand(const std::string & outFile,int time) const334 std::string CreateSplitHtraceCommand(const std::string &outFile, int time) const 335 { 336 std::string cmdStr = 337 "hiprofiler_cmd -s -k \\\n" 338 "-c - \\\n"; 339 cmdStr += "-o " + outFile + " \\\n"; 340 cmdStr += "-t " + std::to_string(time) + " \\\n" 341 "<<CONFIG\n" 342 "request_id: 1\n" 343 "session_config {\n" 344 " buffers {\n" 345 " pages: 16384\n" 346 " }\n" 347 " split_file: true\n" 348 "}\n" 349 "plugin_configs {\n" 350 " plugin_name: \"ftrace-plugin\"\n" 351 " sample_interval: 1000\n" 352 " config_data {\n" 353 " ftrace_events: \"sched/sched_switch\"\n" 354 " ftrace_events: \"sched/sched_wakeup\"\n" 355 " ftrace_events: \"sched/sched_wakeup_new\"\n" 356 " ftrace_events: \"sched/sched_waking\"\n" 357 " ftrace_events: \"sched/sched_process_exit\"\n" 358 " ftrace_events: \"sched/sched_process_free\"\n" 359 " buffer_size_kb: 51200\n" 360 " flush_interval_ms: 1000\n" 361 " flush_threshold_kb: 4096\n" 362 " parse_ksyms: true\n" 363 " clock: \"mono\"\n" 364 " trace_period_ms: 200\n" 365 " debug_on: false\n" 366 " }\n" 367 "}\n" 368 "CONFIG\n"; 369 return cmdStr; 370 } 371 CreateSplitArktsCommand(const std::string & outFile,const std::string & arktsSplitFile,int time) const372 std::string CreateSplitArktsCommand(const std::string &outFile, const std::string &arktsSplitFile, int time) const 373 { 374 std::string cmdStr = 375 "hiprofiler_cmd -s -k \\\n" 376 "-c - \\\n"; 377 cmdStr += "-o " + outFile + " \\\n"; 378 cmdStr += "-t " + std::to_string(time) + " \\\n" 379 "<<CONFIG\n" 380 "request_id: 1\n" 381 "session_config {\n" 382 " buffers {\n" 383 " pages: 16384\n" 384 " }\n" 385 " split_file: true\n" 386 "}\n" 387 "plugin_configs {\n" 388 " plugin_name: \"arkts-plugin\"\n" 389 " config_data {\n" 390 " pid: 1\n" 391 " capture_numeric_value: true\n" 392 " track_allocations: false\n" 393 " enable_cpu_profiler: true\n" 394 " cpu_profiler_interval: 1000\n" 395 " split_outfile_name: \"" + arktsSplitFile + "\"\n" 396 " }\n" 397 "}\n" 398 "CONFIG\n"; 399 return cmdStr; 400 } 401 CreateSplitHiperfCommand(const std::string & outFile,const std::string & perfFile,const std::string & perfSplitFile,int time) const402 std::string CreateSplitHiperfCommand(const std::string &outFile, const std::string &perfFile, 403 const std::string &perfSplitFile, int time) const 404 { 405 std::string cmdStr = 406 "hiprofiler_cmd -s -k \\\n" 407 "-c - \\\n"; 408 cmdStr += "-o " + outFile + " \\\n"; 409 cmdStr += "-t " + std::to_string(time) + " \\\n" 410 "<<CONFIG\n" 411 "request_id: 1\n" 412 "session_config {\n" 413 " buffers {\n" 414 " pages: 16384\n" 415 " }\n" 416 " split_file: true\n" 417 "}\n" 418 "plugin_configs {\n" 419 " plugin_name: \"hiperf-plugin\"\n" 420 " config_data {\n" 421 " is_root: false\n" 422 " outfile_name: \"" + perfFile + "\"\n" 423 " record_args: \"-f 1000 -a --cpu-limit 100 -e hw-cpu-cycles,sched:sched_waking --call-stack dwarf --clockid monotonic --offcpu -m 256\"\n" 424 " split_outfile_name: \"" + perfSplitFile + "\"\n" 425 " }\n" 426 "}\n" 427 "CONFIG\n"; 428 return cmdStr; 429 } 430 CreateSplitHiebpfCommand(const std::string & outFile,const std::string & ebpfFile,const std::string & ebpfSplitFile,int time) const431 std::string CreateSplitHiebpfCommand(const std::string &outFile, const std::string &ebpfFile, 432 const std::string &ebpfSplitFile, int time) const 433 { 434 std::string cmdStr = 435 "hiprofiler_cmd -s -k \\\n" 436 "-c - \\\n"; 437 cmdStr += "-o " + outFile + " \\\n"; 438 cmdStr += "-t " + std::to_string(time) + " \\\n" 439 "<<CONFIG\n" 440 "request_id: 1\n" 441 "session_config {\n" 442 " buffers {\n" 443 " pages: 16384\n" 444 " }\n" 445 " split_file: true\n" 446 "}\n" 447 "plugin_configs {\n" 448 " plugin_name: \"hiebpf-plugin\"\n" 449 " config_data {\n" 450 " cmd_line: \"hiebpf --events fs,ptrace,bio --duration 200 --max_stack_depth 10\"\n" 451 " outfile_name: \"" + ebpfFile + "\"\n" 452 " split_outfile_name: \"" + ebpfSplitFile + "\"\n" 453 " }\n" 454 "}\n" 455 "CONFIG\n"; 456 return cmdStr; 457 } 458 GetFileSize(const char * filename)459 unsigned long GetFileSize(const char* filename) 460 { 461 struct stat buf; 462 463 if (stat(filename, &buf) < 0) { 464 return 0; 465 } 466 return static_cast<unsigned long>(buf.st_size); 467 } 468 KillProcess(const std::string processName)469 void KillProcess(const std::string processName) 470 { 471 int pid = -1; 472 std::string findpid = "pidof " + processName; 473 PROFILER_LOG_INFO(LOG_CORE, "find pid command : %s", findpid.c_str()); 474 std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(findpid.c_str(), "r"), pclose); 475 476 char line[LINE_SIZE]; 477 do { 478 if (fgets(line, sizeof(line), pipe.get()) == nullptr) { 479 PROFILER_LOG_INFO(LOG_CORE, "not find processName : %s", processName.c_str()); 480 return; 481 } else if (strlen(line) > 0 && isdigit(static_cast<unsigned char>(line[0]))) { 482 pid = atoi(line); 483 PROFILER_LOG_INFO(LOG_CORE, "find processName : %s, pid: %d", processName.c_str(), pid); 484 break; 485 } 486 } while (1); 487 488 if (pid != -1) { 489 StopProcessStub(pid); 490 } 491 } 492 private: 493 int hiprofilerdPid_ = -1; 494 int hiprofilerPluginsPid_ = -1; 495 }; 496 497 /** 498 * @tc.name: hiprofiler_cmd 499 * @tc.desc: Test hiprofiler_cmd with -h -q. 500 * @tc.type: FUNC 501 */ 502 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0110, Function | MediumTest | Level1) 503 { 504 KillProcess(DEFAULT_HIPROFILERD_NAME); 505 KillProcess(DEFAULT_HIPROFILER_PLUGINS_NAME); 506 507 std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -h"; 508 std::string content = ""; 509 EXPECT_TRUE(RunCommand(cmd, content)); 510 std::string destStr = "help"; 511 EXPECT_EQ(strncmp(content.c_str(), destStr.c_str(), strlen(destStr.c_str())), 0); 512 513 content = ""; 514 cmd = DEFAULT_HIPROFILER_CMD_PATH + " -q"; 515 EXPECT_TRUE(RunCommand(cmd, content)); 516 destStr = "Service not started"; 517 EXPECT_EQ(strncmp(content.c_str(), destStr.c_str(), strlen(destStr.c_str())), 0); 518 519 StartServerStub(DEFAULT_HIPROFILERD_PATH); 520 sleep(1); 521 content = ""; 522 EXPECT_TRUE(RunCommand(cmd, content)); 523 destStr = "OK"; 524 EXPECT_EQ(strncmp(content.c_str(), destStr.c_str(), strlen(destStr.c_str())), 0); 525 StopProcessStub(hiprofilerdPid_); 526 } 527 528 /** 529 * @tc.name: hiprofiler_cmd 530 * @tc.desc: Test hiprofiler_cmd with -c file. 531 * @tc.type: FUNC 532 */ 533 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0120, Function | MediumTest | Level1) 534 { 535 KillProcess(DEFAULT_HIPROFILERD_NAME); 536 KillProcess(DEFAULT_HIPROFILER_PLUGINS_NAME); 537 538 // 测试不存在的config文件 539 std::string configTestFile = DEFAULT_PATH + "1234.txt"; 540 std::string outFile = DEFAULT_PATH + "trace.htrace"; 541 std::string content = ""; 542 std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -c " + configTestFile + " -o " + outFile + " -t 3"; 543 EXPECT_TRUE(RunCommand(cmd, content)); 544 std::string destStr = "Read " + configTestFile + " fail"; 545 EXPECT_TRUE(content.find(destStr) != std::string::npos); 546 547 // 创建有效的config文件 548 const std::string configFile = DEFAULT_PATH + "ftrace.config"; 549 CreateConfigFile(configFile); 550 551 // 测试有效的config文件,不开启hiprofilerd和hiprofiler_plugin进程 552 content = ""; 553 cmd = DEFAULT_HIPROFILER_CMD_PATH + " -c " + configFile + " -o " + outFile + " -t 3"; 554 EXPECT_TRUE(RunCommand(cmd, content)); 555 sleep(SLEEP_TIME); 556 EXPECT_NE(access(outFile.c_str(), F_OK), 0); 557 558 // 开启hiprofilerd和hiprofiler_plugin进程,可以生成trace文件 559 content = ""; 560 StartServerStub(DEFAULT_HIPROFILERD_PATH); 561 sleep(1); 562 StartServerStub(DEFAULT_HIPROFILER_PLUGINS_PATH); 563 sleep(1); 564 EXPECT_TRUE(RunCommand(cmd, content)); 565 sleep(SLEEP_TIME); 566 EXPECT_EQ(access(outFile.c_str(), F_OK), 0); 567 568 // 删除资源文件和生成的trace文件 569 cmd = "rm " + configFile + " " + outFile; 570 system(cmd.c_str()); 571 StopProcessStub(hiprofilerPluginsPid_); 572 StopProcessStub(hiprofilerdPid_); 573 } 574 575 /** 576 * @tc.name: hiprofiler_cmd 577 * @tc.desc: Test hiprofiler_cmd with -c string. 578 * @tc.type: FUNC 579 */ 580 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0130, Function | MediumTest | Level1) 581 { 582 std::string cmd = "cp " + DEFAULT_SO_PATH + "libftrace_plugin.z.so " + DEFAULT_PATH; 583 system(cmd.c_str()); 584 585 // 开启hiprofilerd和hiprofiler_plugin进程,验证字符串格式的config 586 std::string content = ""; 587 StartServerStub(DEFAULT_HIPROFILERD_PATH); 588 sleep(1); 589 StartServerStub(DEFAULT_HIPROFILER_PLUGINS_PATH); 590 sleep(1); 591 std::string outFile = DEFAULT_PATH + "trace.htrace"; 592 int time = 3; 593 cmd = CreateCommand(outFile, time); 594 EXPECT_TRUE(RunCommand(cmd, content)); 595 sleep(time); 596 EXPECT_EQ(access(outFile.c_str(), F_OK), 0); 597 598 // 删除资源文件和生成的trace文件 599 cmd = "rm " + FTRACE_PLUGIN_PATH + " " + outFile; 600 system(cmd.c_str()); 601 StopProcessStub(hiprofilerPluginsPid_); 602 StopProcessStub(hiprofilerdPid_); 603 } 604 605 /** 606 * @tc.name: hiprofiler_cmd 607 * @tc.desc: Test hiprofiler_cmd with -s -l -k. 608 * @tc.type: FUNC 609 */ 610 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0140, Function | MediumTest | Level1) 611 { 612 KillProcess(DEFAULT_HIPROFILERD_NAME); 613 KillProcess(DEFAULT_HIPROFILER_PLUGINS_NAME); 614 615 std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -s -l -k"; 616 std::string content = ""; 617 EXPECT_TRUE(RunCommand(cmd, content)); 618 std::string destStr = "plugin"; 619 EXPECT_TRUE(content.find(destStr) != std::string::npos); 620 } 621 622 /** 623 * @tc.name: hiprofiler_cmd 624 * @tc.desc: Test hiprofiler_cmd with -l -k. 625 * @tc.type: FUNC 626 */ 627 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0150, Function | MediumTest | Level1) 628 { 629 KillProcess(DEFAULT_HIPROFILERD_NAME); 630 KillProcess(DEFAULT_HIPROFILER_PLUGINS_NAME); 631 632 std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -l -k"; 633 std::string content = ""; 634 EXPECT_TRUE(RunCommand(cmd, content)); 635 } 636 637 /** 638 * @tc.name: hiprofiler_cmd 639 * @tc.desc: Test hiprofiler_cmd with -k. 640 * @tc.type: FUNC 641 */ 642 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0160, Function | MediumTest | Level1) 643 { 644 KillProcess(DEFAULT_HIPROFILERD_NAME); 645 KillProcess(DEFAULT_HIPROFILER_PLUGINS_NAME); 646 647 std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -k"; 648 std::string content = ""; 649 EXPECT_TRUE(RunCommand(cmd, content)); 650 } 651 652 /** 653 * @tc.name: hiprofiler_cmd 654 * @tc.desc: Test hiprofiler_cmd with proto encoder. 655 * @tc.type: FUNC 656 */ 657 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0170, Function | MediumTest | Level1) 658 { 659 std::string cmd = "cp " + DEFAULT_SO_PATH + "libftrace_plugin.z.so " + DEFAULT_PATH; 660 system(cmd.c_str()); 661 662 // 开启hiprofilerd和hiprofiler_plugin进程,验证字符串格式的config 663 std::string content = ""; 664 StartServerStub(DEFAULT_HIPROFILERD_PATH); 665 sleep(1); 666 StartServerStub(DEFAULT_HIPROFILER_PLUGINS_PATH); 667 sleep(1); 668 std::string outFile = DEFAULT_PATH + "trace_encoder.htrace"; 669 int time = 3; 670 cmd = CreateEncoderCommand(outFile, time); 671 EXPECT_TRUE(RunCommand(cmd, content)); 672 sleep(time); 673 EXPECT_EQ(access(outFile.c_str(), F_OK), 0); 674 675 // 删除资源文件和生成的trace文件 676 cmd = "rm " + FTRACE_PLUGIN_PATH + " " + outFile; 677 system(cmd.c_str()); 678 StopProcessStub(hiprofilerPluginsPid_); 679 StopProcessStub(hiprofilerdPid_); 680 } 681 682 /** 683 * @tc.name: hiprofiler_cmd 684 * @tc.desc: Test hiprofiler_cmd with ctrl+c. 685 * @tc.type: FUNC 686 */ 687 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0180, Function | MediumTest | Level1) 688 { 689 std::string content = ""; 690 std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -s"; 691 EXPECT_TRUE(RunCommand(cmd, content)); 692 sleep(2); // 2: wait hiprofilerd start 693 pid_t pid = fork(); 694 EXPECT_GE(pid, 0); 695 if (pid == 0) { 696 content = ""; 697 const int time = 20; 698 std::string outFile = DEFAULT_PATH + "trace.htrace"; 699 cmd = CreateCommand(outFile, time); 700 EXPECT_TRUE(RunCommand(cmd, content)); 701 EXPECT_EQ(access(outFile.c_str(), F_OK), 0); 702 // 删除生成的trace文件 703 cmd = "rm " + outFile; 704 system(cmd.c_str()); 705 _exit(0); 706 } else if (pid > 0) { 707 sleep(1); // 1: wait child process start 708 content = ""; 709 cmd = "pidof hiprofiler_cmd"; 710 EXPECT_TRUE(RunCommand(cmd, content)); 711 ASSERT_STRNE(content.c_str(), ""); 712 cmd = "kill -2 " + content; 713 content = ""; 714 EXPECT_TRUE(RunCommand(cmd, content)); 715 EXPECT_STREQ(content.c_str(), ""); 716 // 等待子进程结束 717 waitpid(pid, nullptr, 0); 718 cmd = DEFAULT_HIPROFILER_CMD_PATH + " -k"; 719 EXPECT_TRUE(RunCommand(cmd, content)); 720 sleep(5); // 5: wait hiprofilerd exit 721 content = ""; 722 cmd = "pidof " + DEFAULT_HIPROFILERD_NAME; 723 EXPECT_TRUE(RunCommand(cmd, content)); 724 EXPECT_STREQ(content.c_str(), ""); 725 } 726 } 727 728 /** 729 * @tc.name: hiprofiler_cmd 730 * @tc.desc: Test hiprofiler_cmd with -c string. 731 * @tc.type: FUNC 732 */ 733 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0190, Function | MediumTest | Level1) 734 { 735 std::string cmd = "cp " + DEFAULT_SO_PATH + "libhiperfplugin.z.so " + DEFAULT_PATH; 736 system(cmd.c_str()); 737 738 // 开启hiprofilerd和hiprofiler_plugin进程,验证字符串格式的config 739 std::string content = ""; 740 StartServerStub(DEFAULT_HIPROFILERD_PATH); 741 sleep(1); 742 StartServerStub(DEFAULT_HIPROFILER_PLUGINS_PATH); 743 sleep(1); 744 std::string outFile = DEFAULT_PATH + "trace.htrace"; 745 int time = 10; 746 cmd = CreateHiperfCommand(outFile, time); 747 EXPECT_TRUE(RunCommand(cmd, content)); 748 sleep(time); 749 EXPECT_EQ(access(outFile.c_str(), F_OK), 0); 750 751 // 删除资源文件和生成的trace文件 752 cmd = "rm " + HIPERF_PLUGIN_PATH + " " + outFile; 753 system(cmd.c_str()); 754 StopProcessStub(hiprofilerPluginsPid_); 755 StopProcessStub(hiprofilerdPid_); 756 } 757 } 758 759 /** 760 * @tc.name: hiprofiler_cmd 761 * @tc.desc: Test hiprofiler_cmd with split Htrace file. 762 * @tc.type: FUNC 763 */ 764 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0200, Function | MediumTest | Level1) 765 { 766 std::string outFileName = "split_htrace"; 767 std::string outFile = DEFAULT_PATH + outFileName + ".htrace"; 768 std::string content = ""; 769 int time = 10; 770 std::string cmd = CreateSplitHtraceCommand(outFile, time); 771 EXPECT_TRUE(RunCommand(cmd, content)); 772 773 EXPECT_NE(access(outFile.c_str(), F_OK), 0); 774 775 cmd = "ls " + DEFAULT_PATH + outFileName + "*_1.htrace"; 776 EXPECT_TRUE(RunCommand(cmd, content)); 777 EXPECT_STRNE(content.c_str(), ""); 778 779 cmd = "rm " + DEFAULT_PATH + outFileName + "*.htrace"; 780 system(cmd.c_str()); 781 } 782 783 /** 784 * @tc.name: hiprofiler_cmd 785 * @tc.desc: Test hiprofiler_cmd with split arkts file. 786 * @tc.type: FUNC 787 */ 788 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0210, Function | MediumTest | Level1) 789 { 790 std::string outFileName = "split_arkts"; 791 std::string outFile = DEFAULT_PATH + outFileName + ".htrace"; 792 std::string arktsSplitFile = "/data/local/tmp/split_arkts_data.htrace"; 793 std::string content = ""; 794 int time = 10; 795 std::string cmd = CreateSplitArktsCommand(outFile, arktsSplitFile, time); 796 EXPECT_TRUE(RunCommand(cmd, content)); 797 798 EXPECT_NE(access(outFile.c_str(), F_OK), 0); 799 800 cmd = "ls " + DEFAULT_PATH + outFileName + "*_1.htrace"; 801 EXPECT_TRUE(RunCommand(cmd, content)); 802 EXPECT_STRNE(content.c_str(), ""); 803 804 EXPECT_EQ(access(arktsSplitFile.c_str(), F_OK), 0); 805 cmd = "rm " + DEFAULT_PATH + outFileName + "*.htrace"; 806 system(cmd.c_str()); 807 } 808 /** 809 * @tc.name: hiprofiler_cmd 810 * @tc.desc: Test hiprofiler_cmd with split hiperf file. 811 * @tc.type: FUNC 812 */ 813 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0220, Function | MediumTest | Level1) 814 { 815 std::string outFileName = "split_hiperf"; 816 std::string outFile = DEFAULT_PATH + outFileName + ".htrace"; 817 std::string perfFile = "/data/local/tmp/perf.data"; 818 std::string perfSplitFile = "/data/local/tmp/split_perf_data.htrace"; 819 std::string content = ""; 820 int time = 10; 821 std::string cmd = CreateSplitHiperfCommand(outFile, perfFile, perfSplitFile, time); 822 EXPECT_TRUE(RunCommand(cmd, content)); 823 824 EXPECT_NE(access(outFile.c_str(), F_OK), 0); 825 826 cmd = "ls " + DEFAULT_PATH + outFileName + "*_1.htrace"; 827 EXPECT_TRUE(RunCommand(cmd, content)); 828 EXPECT_STRNE(content.c_str(), ""); 829 830 EXPECT_EQ(access(perfSplitFile.c_str(), F_OK), 0); 831 if (access(perfFile.c_str(), F_OK) == 0) { 832 const int headerSize = 1024 + 1024; // htrace header + hiperf header 833 auto perfFileSize = GetFileSize(perfFile.c_str()); 834 auto perfSplitFileSize = GetFileSize(perfSplitFile.c_str()); 835 EXPECT_GT(perfSplitFileSize, perfFileSize + headerSize); 836 } 837 838 cmd = "rm " + DEFAULT_PATH + outFileName + "*.htrace " + perfFile + " " + perfSplitFile; 839 system(cmd.c_str()); 840 } 841 /** 842 * @tc.name: hiprofiler_cmd 843 * @tc.desc: Test hiprofiler_cmd with split hiebpf file. 844 * @tc.type: FUNC 845 */ 846 HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0230, Function | MediumTest | Level1) 847 { 848 #if defined(__LP64__) // just support 64bit 849 std::string outFileName = "split_hiebpf"; 850 std::string outFile = DEFAULT_PATH + outFileName + ".htrace"; 851 std::string ebpfFile = "/data/local/tmp/ebpf.data"; 852 std::string ebpfSplitFile = "/data/local/tmp/split_ebpf_data.htrace"; 853 std::string content = ""; 854 int time = 10; 855 std::string cmd = CreateSplitHiebpfCommand(outFile, ebpfFile, ebpfSplitFile, time); 856 EXPECT_TRUE(RunCommand(cmd, content)); 857 858 EXPECT_NE(access(outFile.c_str(), F_OK), 0); 859 860 cmd = "ls " + DEFAULT_PATH + outFileName + "*_1.htrace"; 861 EXPECT_TRUE(RunCommand(cmd, content)); 862 EXPECT_STRNE(content.c_str(), ""); 863 864 EXPECT_EQ(access(ebpfSplitFile.c_str(), F_OK), 0); 865 if (access(ebpfFile.c_str(), F_OK) == 0) { 866 const int headerSize = 1024 + 1024; // htrace header + hiebpf header 867 auto ebpfFileSize = GetFileSize(ebpfFile.c_str()); 868 auto ebpfSplitFileSize = GetFileSize(ebpfSplitFile.c_str()); 869 EXPECT_GT(ebpfSplitFileSize, ebpfFileSize + headerSize); 870 } 871 872 cmd = "rm " + DEFAULT_PATH + outFileName + "*.htrace " + ebpfFile + " " + ebpfSplitFile; 873 system(cmd.c_str()); 874 #endif 875 } 876