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 27using namespace testing::ext; 28 29#define HHB(v) (((v) & 0xF0) >> 4) 30#define LHB(v) ((v) & 0x0F) 31 32namespace { 33#if defined(__LP64__) 34const std::string DEFAULT_SO_PATH("/system/lib64/"); 35#else 36const std::string DEFAULT_SO_PATH("/system/lib/"); 37#endif 38const std::string DEFAULT_HIPROFILERD_PATH("/system/bin/hiprofilerd"); 39const std::string DEFAULT_HIPROFILER_PLUGINS_PATH("/system/bin/hiprofiler_plugins"); 40const std::string DEFAULT_HIPROFILERD_NAME("hiprofilerd"); 41const std::string DEFAULT_HIPROFILER_PLUGINS_NAME("hiprofiler_plugins"); 42 43const std::string DEFAULT_HIPROFILER_CMD_PATH("/system/bin/hiprofiler_cmd"); 44const std::string FTRACE_PLUGIN_PATH("/data/local/tmp/libftrace_plugin.z.so"); 45const std::string HIPERF_PLUGIN_PATH("/data/local/tmp/libhiperfplugin.z.so"); 46std::string DEFAULT_PATH("/data/local/tmp/"); 47constexpr uint32_t READ_BUFFER_SIZE = 1024; 48constexpr int SLEEP_TIME = 3; 49constexpr int FILE_READ_CHUNK_SIZE = 4096; 50constexpr char HEX_CHARS[] = "0123456789abcdef"; 51constexpr int LINE_SIZE = 1000; 52 53 54class HiprofilerCmdTest : public ::testing::Test { 55public: 56 static void SetUpTestCase() {} 57 static void TearDownTestCase() {} 58 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 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 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 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 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 217 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 260 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 291 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 333 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 371 std::string CreateSplitHiperfCommand(const std::string &outFile, const std::string &perfFile, 372 const std::string &perfSplitFile, 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: \"hiperf-plugin\"\n" 389 " config_data {\n" 390 " is_root: false\n" 391 " outfile_name: \"" + perfFile + "\"\n" 392 " record_args: \"-f 1000 -a --cpu-limit 100 -e hw-cpu-cycles,sched:sched_waking --call-stack dwarf --clockid monotonic --offcpu -m 256\"\n" 393 " split_outfile_name: \"" + perfSplitFile + "\"\n" 394 " }\n" 395 "}\n" 396 "CONFIG\n"; 397 return cmdStr; 398 } 399 400 std::string CreateSplitHiebpfCommand(const std::string &outFile, const std::string &ebpfFile, 401 const std::string &ebpfSplitFile, int time) const 402 { 403 std::string cmdStr = 404 "hiprofiler_cmd -s -k \\\n" 405 "-c - \\\n"; 406 cmdStr += "-o " + outFile + " \\\n"; 407 cmdStr += "-t " + std::to_string(time) + " \\\n" 408 "<<CONFIG\n" 409 "request_id: 1\n" 410 "session_config {\n" 411 " buffers {\n" 412 " pages: 16384\n" 413 " }\n" 414 " split_file: true\n" 415 "}\n" 416 "plugin_configs {\n" 417 " plugin_name: \"hiebpf-plugin\"\n" 418 " config_data {\n" 419 " cmd_line: \"hiebpf --events fs,ptrace,bio --duration 200 --max_stack_depth 10\"\n" 420 " outfile_name: \"" + ebpfFile + "\"\n" 421 " split_outfile_name: \"" + ebpfSplitFile + "\"\n" 422 " }\n" 423 "}\n" 424 "CONFIG\n"; 425 return cmdStr; 426 } 427 428 unsigned long GetFileSize(const char* filename) 429 { 430 struct stat buf; 431 432 if (stat(filename, &buf) < 0) { 433 return 0; 434 } 435 return static_cast<unsigned long>(buf.st_size); 436 } 437 438 void KillProcess(const std::string processName) 439 { 440 int pid = -1; 441 std::string findpid = "pidof " + processName; 442 PROFILER_LOG_INFO(LOG_CORE, "find pid command : %s", findpid.c_str()); 443 std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(findpid.c_str(), "r"), pclose); 444 445 char line[LINE_SIZE]; 446 do { 447 if (fgets(line, sizeof(line), pipe.get()) == nullptr) { 448 PROFILER_LOG_INFO(LOG_CORE, "not find processName : %s", processName.c_str()); 449 return; 450 } else if (strlen(line) > 0 && isdigit(static_cast<unsigned char>(line[0]))) { 451 pid = atoi(line); 452 PROFILER_LOG_INFO(LOG_CORE, "find processName : %s, pid: %d", processName.c_str(), pid); 453 break; 454 } 455 } while (1); 456 457 if (pid != -1) { 458 StopProcessStub(pid); 459 } 460 } 461private: 462 int hiprofilerdPid_ = -1; 463 int hiprofilerPluginsPid_ = -1; 464}; 465 466/** 467 * @tc.name: hiprofiler_cmd 468 * @tc.desc: Test hiprofiler_cmd with -h -q. 469 * @tc.type: FUNC 470 */ 471HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0110, Function | MediumTest | Level1) 472{ 473 KillProcess(DEFAULT_HIPROFILERD_NAME); 474 KillProcess(DEFAULT_HIPROFILER_PLUGINS_NAME); 475 476 std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -h"; 477 std::string content = ""; 478 EXPECT_TRUE(RunCommand(cmd, content)); 479 std::string destStr = "help"; 480 EXPECT_EQ(strncmp(content.c_str(), destStr.c_str(), strlen(destStr.c_str())), 0); 481 482 content = ""; 483 cmd = DEFAULT_HIPROFILER_CMD_PATH + " -q"; 484 EXPECT_TRUE(RunCommand(cmd, content)); 485 destStr = "Service not started"; 486 EXPECT_EQ(strncmp(content.c_str(), destStr.c_str(), strlen(destStr.c_str())), 0); 487 488 StartServerStub(DEFAULT_HIPROFILERD_PATH); 489 sleep(1); 490 content = ""; 491 EXPECT_TRUE(RunCommand(cmd, content)); 492 destStr = "OK"; 493 EXPECT_EQ(strncmp(content.c_str(), destStr.c_str(), strlen(destStr.c_str())), 0); 494 StopProcessStub(hiprofilerdPid_); 495} 496 497/** 498 * @tc.name: hiprofiler_cmd 499 * @tc.desc: Test hiprofiler_cmd with -c file. 500 * @tc.type: FUNC 501 */ 502HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0120, Function | MediumTest | Level1) 503{ 504 KillProcess(DEFAULT_HIPROFILERD_NAME); 505 KillProcess(DEFAULT_HIPROFILER_PLUGINS_NAME); 506 507 // 测试不存在的config文件 508 std::string configTestFile = DEFAULT_PATH + "1234.txt"; 509 std::string outFile = DEFAULT_PATH + "trace.htrace"; 510 std::string content = ""; 511 std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -c " + configTestFile + " -o " + outFile + " -t 3"; 512 EXPECT_TRUE(RunCommand(cmd, content)); 513 std::string destStr = "Read " + configTestFile + " fail"; 514 EXPECT_TRUE(content.find(destStr) != std::string::npos); 515 516 // 创建有效的config文件 517 const std::string configFile = DEFAULT_PATH + "ftrace.config"; 518 CreateConfigFile(configFile); 519 520 // 测试有效的config文件,不开启hiprofilerd和hiprofiler_plugin进程 521 content = ""; 522 cmd = DEFAULT_HIPROFILER_CMD_PATH + " -c " + configFile + " -o " + outFile + " -t 3"; 523 EXPECT_TRUE(RunCommand(cmd, content)); 524 sleep(SLEEP_TIME); 525 EXPECT_NE(access(outFile.c_str(), F_OK), 0); 526 527 // 开启hiprofilerd和hiprofiler_plugin进程,可以生成trace文件 528 content = ""; 529 StartServerStub(DEFAULT_HIPROFILERD_PATH); 530 sleep(1); 531 StartServerStub(DEFAULT_HIPROFILER_PLUGINS_PATH); 532 sleep(1); 533 EXPECT_TRUE(RunCommand(cmd, content)); 534 sleep(SLEEP_TIME); 535 EXPECT_EQ(access(outFile.c_str(), F_OK), 0); 536 537 // 删除资源文件和生成的trace文件 538 cmd = "rm " + configFile + " " + outFile; 539 system(cmd.c_str()); 540 StopProcessStub(hiprofilerPluginsPid_); 541 StopProcessStub(hiprofilerdPid_); 542} 543 544/** 545 * @tc.name: hiprofiler_cmd 546 * @tc.desc: Test hiprofiler_cmd with -c string. 547 * @tc.type: FUNC 548 */ 549HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0130, Function | MediumTest | Level1) 550{ 551 std::string cmd = "cp " + DEFAULT_SO_PATH + "libftrace_plugin.z.so " + DEFAULT_PATH; 552 system(cmd.c_str()); 553 554 // 开启hiprofilerd和hiprofiler_plugin进程,验证字符串格式的config 555 std::string content = ""; 556 StartServerStub(DEFAULT_HIPROFILERD_PATH); 557 sleep(1); 558 StartServerStub(DEFAULT_HIPROFILER_PLUGINS_PATH); 559 sleep(1); 560 std::string outFile = DEFAULT_PATH + "trace.htrace"; 561 int time = 3; 562 cmd = CreateCommand(outFile, time); 563 EXPECT_TRUE(RunCommand(cmd, content)); 564 sleep(time); 565 EXPECT_EQ(access(outFile.c_str(), F_OK), 0); 566 567 // 删除资源文件和生成的trace文件 568 cmd = "rm " + FTRACE_PLUGIN_PATH + " " + 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 -s -l -k. 577 * @tc.type: FUNC 578 */ 579HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0140, Function | MediumTest | Level1) 580{ 581 KillProcess(DEFAULT_HIPROFILERD_NAME); 582 KillProcess(DEFAULT_HIPROFILER_PLUGINS_NAME); 583 584 std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -s -l -k"; 585 std::string content = ""; 586 EXPECT_TRUE(RunCommand(cmd, content)); 587 std::string destStr = "plugin"; 588 EXPECT_TRUE(content.find(destStr) != std::string::npos); 589} 590 591/** 592 * @tc.name: hiprofiler_cmd 593 * @tc.desc: Test hiprofiler_cmd with -l -k. 594 * @tc.type: FUNC 595 */ 596HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0150, Function | MediumTest | Level1) 597{ 598 KillProcess(DEFAULT_HIPROFILERD_NAME); 599 KillProcess(DEFAULT_HIPROFILER_PLUGINS_NAME); 600 601 std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -l -k"; 602 std::string content = ""; 603 EXPECT_TRUE(RunCommand(cmd, content)); 604} 605 606/** 607 * @tc.name: hiprofiler_cmd 608 * @tc.desc: Test hiprofiler_cmd with -k. 609 * @tc.type: FUNC 610 */ 611HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0160, Function | MediumTest | Level1) 612{ 613 KillProcess(DEFAULT_HIPROFILERD_NAME); 614 KillProcess(DEFAULT_HIPROFILER_PLUGINS_NAME); 615 616 std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -k"; 617 std::string content = ""; 618 EXPECT_TRUE(RunCommand(cmd, content)); 619} 620 621/** 622 * @tc.name: hiprofiler_cmd 623 * @tc.desc: Test hiprofiler_cmd with proto encoder. 624 * @tc.type: FUNC 625 */ 626HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0170, Function | MediumTest | Level1) 627{ 628 std::string cmd = "cp " + DEFAULT_SO_PATH + "libftrace_plugin.z.so " + DEFAULT_PATH; 629 system(cmd.c_str()); 630 631 // 开启hiprofilerd和hiprofiler_plugin进程,验证字符串格式的config 632 std::string content = ""; 633 StartServerStub(DEFAULT_HIPROFILERD_PATH); 634 sleep(1); 635 StartServerStub(DEFAULT_HIPROFILER_PLUGINS_PATH); 636 sleep(1); 637 std::string outFile = DEFAULT_PATH + "trace_encoder.htrace"; 638 int time = 3; 639 cmd = CreateEncoderCommand(outFile, time); 640 EXPECT_TRUE(RunCommand(cmd, content)); 641 sleep(time); 642 EXPECT_EQ(access(outFile.c_str(), F_OK), 0); 643 644 // 删除资源文件和生成的trace文件 645 cmd = "rm " + FTRACE_PLUGIN_PATH + " " + outFile; 646 system(cmd.c_str()); 647 StopProcessStub(hiprofilerPluginsPid_); 648 StopProcessStub(hiprofilerdPid_); 649} 650 651/** 652 * @tc.name: hiprofiler_cmd 653 * @tc.desc: Test hiprofiler_cmd with ctrl+c. 654 * @tc.type: FUNC 655 */ 656HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0180, Function | MediumTest | Level1) 657{ 658 std::string content = ""; 659 std::string cmd = DEFAULT_HIPROFILER_CMD_PATH + " -s"; 660 EXPECT_TRUE(RunCommand(cmd, content)); 661 sleep(2); // 2: wait hiprofilerd start 662 pid_t pid = fork(); 663 EXPECT_GE(pid, 0); 664 if (pid == 0) { 665 content = ""; 666 const int time = 20; 667 std::string outFile = DEFAULT_PATH + "trace.htrace"; 668 cmd = CreateCommand(outFile, time); 669 EXPECT_TRUE(RunCommand(cmd, content)); 670 EXPECT_EQ(access(outFile.c_str(), F_OK), 0); 671 // 删除生成的trace文件 672 cmd = "rm " + outFile; 673 system(cmd.c_str()); 674 _exit(0); 675 } else if (pid > 0) { 676 sleep(1); // 1: wait child process start 677 content = ""; 678 cmd = "pidof hiprofiler_cmd"; 679 EXPECT_TRUE(RunCommand(cmd, content)); 680 ASSERT_STRNE(content.c_str(), ""); 681 cmd = "kill -2 " + content; 682 content = ""; 683 EXPECT_TRUE(RunCommand(cmd, content)); 684 EXPECT_STREQ(content.c_str(), ""); 685 // 等待子进程结束 686 waitpid(pid, nullptr, 0); 687 cmd = DEFAULT_HIPROFILER_CMD_PATH + " -k"; 688 EXPECT_TRUE(RunCommand(cmd, content)); 689 sleep(5); // 5: wait hiprofilerd exit 690 content = ""; 691 cmd = "pidof " + DEFAULT_HIPROFILERD_NAME; 692 EXPECT_TRUE(RunCommand(cmd, content)); 693 EXPECT_STREQ(content.c_str(), ""); 694 } 695} 696 697/** 698 * @tc.name: hiprofiler_cmd 699 * @tc.desc: Test hiprofiler_cmd with -c string. 700 * @tc.type: FUNC 701 */ 702HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0190, Function | MediumTest | Level1) 703{ 704 std::string cmd = "cp " + DEFAULT_SO_PATH + "libhiperfplugin.z.so " + DEFAULT_PATH; 705 system(cmd.c_str()); 706 707 // 开启hiprofilerd和hiprofiler_plugin进程,验证字符串格式的config 708 std::string content = ""; 709 StartServerStub(DEFAULT_HIPROFILERD_PATH); 710 sleep(1); 711 StartServerStub(DEFAULT_HIPROFILER_PLUGINS_PATH); 712 sleep(1); 713 std::string outFile = DEFAULT_PATH + "trace.htrace"; 714 int time = 10; 715 cmd = CreateHiperfCommand(outFile, time); 716 EXPECT_TRUE(RunCommand(cmd, content)); 717 sleep(time); 718 EXPECT_EQ(access(outFile.c_str(), F_OK), 0); 719 720 // 删除资源文件和生成的trace文件 721 cmd = "rm " + HIPERF_PLUGIN_PATH + " " + outFile; 722 system(cmd.c_str()); 723 StopProcessStub(hiprofilerPluginsPid_); 724 StopProcessStub(hiprofilerdPid_); 725} 726} 727 728/** 729 * @tc.name: hiprofiler_cmd 730 * @tc.desc: Test hiprofiler_cmd with split Htrace file. 731 * @tc.type: FUNC 732 */ 733HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0200, Function | MediumTest | Level1) 734{ 735 std::string outFileName = "split_htrace"; 736 std::string outFile = DEFAULT_PATH + outFileName + ".htrace"; 737 std::string content = ""; 738 int time = 10; 739 std::string cmd = CreateSplitHtraceCommand(outFile, time); 740 EXPECT_TRUE(RunCommand(cmd, content)); 741 742 EXPECT_NE(access(outFile.c_str(), F_OK), 0); 743 744 cmd = "ls " + DEFAULT_PATH + outFileName + "*_1.htrace"; 745 EXPECT_TRUE(RunCommand(cmd, content)); 746 EXPECT_STRNE(content.c_str(), ""); 747 748 cmd = "rm " + DEFAULT_PATH + outFileName + "*.htrace"; 749 system(cmd.c_str()); 750} 751 752/** 753 * @tc.name: hiprofiler_cmd 754 * @tc.desc: Test hiprofiler_cmd with split hiperf file. 755 * @tc.type: FUNC 756 */ 757HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0220, Function | MediumTest | Level1) 758{ 759 std::string outFileName = "split_hiperf"; 760 std::string outFile = DEFAULT_PATH + outFileName + ".htrace"; 761 std::string perfFile = "/data/local/tmp/perf.data"; 762 std::string perfSplitFile = "/data/local/tmp/split_perf_data.htrace"; 763 std::string content = ""; 764 int time = 10; 765 std::string cmd = CreateSplitHiperfCommand(outFile, perfFile, perfSplitFile, time); 766 EXPECT_TRUE(RunCommand(cmd, content)); 767 768 EXPECT_NE(access(outFile.c_str(), F_OK), 0); 769 770 cmd = "ls " + DEFAULT_PATH + outFileName + "*_1.htrace"; 771 EXPECT_TRUE(RunCommand(cmd, content)); 772 EXPECT_STRNE(content.c_str(), ""); 773 774 EXPECT_EQ(access(perfSplitFile.c_str(), F_OK), 0); 775 if (access(perfFile.c_str(), F_OK) == 0) { 776 const int headerSize = 1024 + 1024; // htrace header + hiperf header 777 auto perfFileSize = GetFileSize(perfFile.c_str()); 778 auto perfSplitFileSize = GetFileSize(perfSplitFile.c_str()); 779 EXPECT_GT(perfSplitFileSize, perfFileSize + headerSize); 780 } 781 782 cmd = "rm " + DEFAULT_PATH + outFileName + "*.htrace " + perfFile + " " + perfSplitFile; 783 system(cmd.c_str()); 784} 785/** 786 * @tc.name: hiprofiler_cmd 787 * @tc.desc: Test hiprofiler_cmd with split hiebpf file. 788 * @tc.type: FUNC 789 */ 790HWTEST_F(HiprofilerCmdTest, DFX_DFR_Hiprofiler_0230, Function | MediumTest | Level1) 791{ 792#if defined(__LP64__) // just support 64bit 793 std::string outFileName = "split_hiebpf"; 794 std::string outFile = DEFAULT_PATH + outFileName + ".htrace"; 795 std::string ebpfFile = "/data/local/tmp/ebpf.data"; 796 std::string ebpfSplitFile = "/data/local/tmp/split_ebpf_data.htrace"; 797 std::string content = ""; 798 int time = 10; 799 std::string cmd = CreateSplitHiebpfCommand(outFile, ebpfFile, ebpfSplitFile, time); 800 EXPECT_TRUE(RunCommand(cmd, content)); 801 802 EXPECT_NE(access(outFile.c_str(), F_OK), 0); 803 804 cmd = "ls " + DEFAULT_PATH + outFileName + "*_1.htrace"; 805 EXPECT_TRUE(RunCommand(cmd, content)); 806 EXPECT_STRNE(content.c_str(), ""); 807 808 EXPECT_EQ(access(ebpfSplitFile.c_str(), F_OK), 0); 809 if (access(ebpfFile.c_str(), F_OK) == 0) { 810 const int headerSize = 1024 + 1024; // htrace header + hiebpf header 811 auto ebpfFileSize = GetFileSize(ebpfFile.c_str()); 812 auto ebpfSplitFileSize = GetFileSize(ebpfSplitFile.c_str()); 813 EXPECT_GT(ebpfSplitFileSize, ebpfFileSize + headerSize); 814 } 815 816 cmd = "rm " + DEFAULT_PATH + outFileName + "*.htrace " + ebpfFile + " " + ebpfSplitFile; 817 system(cmd.c_str()); 818#endif 819} 820