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