• 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 <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