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