• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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