• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
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 "subcommand_record_test.h"
17 
18 #include <algorithm>
19 #include <chrono>
20 #include <cinttypes>
21 #include <sched.h>
22 #include <sstream>
23 #include <sys/stat.h>
24 #include <sys/utsname.h>
25 #include <thread>
26 #include <poll.h>
27 #include <unistd.h>
28 
29 #include "command.h"
30 #include "debug_logger.h"
31 #include "hisysevent_manager.h"
32 #include "perf_pipe.h"
33 #include "subcommand_dump.h"
34 #include "subcommand_report.h"
35 #include "subcommand_test.h"
36 #include "test_hiperf_event_listener.h"
37 #include "test_utilities.h"
38 #include "utilities.h"
39 
40 using namespace std::literals::chrono_literals;
41 using namespace testing::ext;
42 namespace OHOS {
43 namespace Developtools {
44 namespace HiPerf {
45 static const std::string TEST_FILE = "/data/local/tmp/perf.data";
46 const std::string PERF_CPU_TIME_MAX_PERCENT = "/proc/sys/kernel/perf_cpu_time_max_percent";
47 static const std::chrono::milliseconds CONTROL_WAITREPY_TOMEOUT = 2ms;
48 
49 class SubCommandRecordTest : public testing::Test {
50 public:
51     static void SetUpTestCase(void);
52     static void TearDownTestCase(void);
53     void SetUp();
54     void TearDown();
55 
56     void TestEvents(std::string &opt, std::string &uk, bool isFork = true);
57 
58     static void ForkAndRunTest(const std::string& cmd, bool expect = true, bool fixPid = true,
59                                SubCommandRecord::CheckRecordCallBack callback = nullptr);
60 
61     static void TestRecordCommand(const std::string &option, bool expect = true, bool fixPid = true,
62                                   SubCommandRecord::CheckRecordCallBack callback = nullptr);
63 
64     static bool TestRecordCommandForFork(const std::string &option, bool expect = true, bool fixPid = true,
65                                          SubCommandRecord::CheckRecordCallBack callback = nullptr);
66 
67     size_t GetFileSize(const char* fileName);
68 
69     static std::string testProcesses;
70 };
71 
72 std::string SubCommandRecordTest::testProcesses = "com.ohos.launcher";
73 
SetUpTestCase()74 void SubCommandRecordTest::SetUpTestCase() {}
75 
TearDownTestCase()76 void SubCommandRecordTest::TearDownTestCase() {}
77 
SetUp()78 void SubCommandRecordTest::SetUp()
79 {
80     if (!CheckTestApp(SubCommandRecordTest::testProcesses)) {
81         SubCommandRecordTest::testProcesses = "hiview";
82     }
83     SubCommand::ClearSubCommands(); // clear the subCommands left from other UT
84     ASSERT_EQ(SubCommand::GetSubCommands().size(), 0u);
85     SubCommand::RegisterSubCommand("record", std::make_unique<SubCommandRecord>());
86     ASSERT_EQ(SubCommand::GetSubCommands().size(), 1u);
87     SubCommand::RegisterSubCommand("dump", std::make_unique<SubCommandDump>());
88     SubCommand::RegisterSubCommand("report", std::make_unique<SubCommandReport>());
89     SubCommand::RegisterSubCommand("TEST_CMD_1", std::make_unique<SubCommandTest>("TEST_CMD_1"));
90 }
91 
TearDown()92 void SubCommandRecordTest::TearDown()
93 {
94     ASSERT_EQ(SubCommand::GetSubCommands().size(), 4u);
95     SubCommand::ClearSubCommands();
96     ASSERT_EQ(SubCommand::GetSubCommands().size(), 0u);
97     MemoryHold::Get().Clean();
98 }
99 
TestRecordCommandForFork(const std::string & option,bool expect,bool fixPid,SubCommandRecord::CheckRecordCallBack callback)100 bool SubCommandRecordTest::TestRecordCommandForFork(const std::string &option, bool expect, bool fixPid,
101                                                     SubCommandRecord::CheckRecordCallBack callback)
102 {
103     StdoutRecord stdoutRecord;
104     std::string cmdString = "record ";
105     if (fixPid) {
106         cmdString += "--app ";
107         cmdString += " " + testProcesses;
108     }
109     cmdString += " " + option;
110     printf("command : %s\n", cmdString.c_str());
111 
112     if (callback != nullptr) {
113         std::string subcommandName = "record";
114         SubCommand* subcommand = SubCommand::FindSubCommand(subcommandName);
115         if (subcommand == nullptr) {
116             return false;
117         }
118         SubCommandRecord* subcommandRecord = static_cast<SubCommandRecord*>(subcommand);
119         subcommandRecord->SetCheckRecordCallback(callback);
120     }
121 
122     // it need load some symbols and much more log
123     stdoutRecord.Start();
124     const auto startTime = std::chrono::steady_clock::now();
125     bool ret = Command::DispatchCommand(cmdString);
126     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
127     std::chrono::steady_clock::now() - startTime);
128     std::string stringOut = stdoutRecord.Stop();
129     if ((stringOut.find("Sample records:") != std::string::npos) != expect) {
130         GTEST_LOG_(ERROR) << "stringOut:" << stringOut << ret;
131         return false;
132     }
133     printf("run %" PRId64 " ms return %s(expect %s)\n", (uint64_t)costMs.count(), ret ? "true" : "false",
134            expect ? "true" : "false");
135     return true;
136 }
137 
ForkAndRunTest(const std::string & cmd,bool expect,bool fixPid,SubCommandRecord::CheckRecordCallBack callback)138 void SubCommandRecordTest::ForkAndRunTest(const std::string& cmd, bool expect, bool fixPid,
139                                           SubCommandRecord::CheckRecordCallBack callback)
140 {
141     pid_t pid = fork();
142     if (pid < 0) {
143         FAIL() << "Fork test process failed";
144         return;
145     }
146     if (pid == 0) {
147         bool result = TestRecordCommandForFork(cmd, expect, fixPid, callback);
148         _exit(result ? 0 : 1);
149     }
150     int status;
151     int ret = wait(&status);
152     GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
153     ASSERT_EQ(status, 0);
154 }
155 
TestRecordCommand(const std::string & option,bool expect,bool fixPid,SubCommandRecord::CheckRecordCallBack callback)156 void SubCommandRecordTest::TestRecordCommand(const std::string &option, bool expect, bool fixPid,
157                                              SubCommandRecord::CheckRecordCallBack callback)
158 {
159     StdoutRecord stdoutRecord;
160 
161     std::string cmdString = "record ";
162     if (fixPid) {
163         cmdString += "--app ";
164         cmdString += " " + testProcesses;
165     }
166     cmdString += " " + option;
167     printf("command : %s\n", cmdString.c_str());
168 
169     if (callback != nullptr) {
170         std::string subcommandName = "record";
171         SubCommand* subcommand = SubCommand::FindSubCommand(subcommandName);
172         ASSERT_NE(subcommand, nullptr);
173         SubCommandRecord* subcommandRecord = static_cast<SubCommandRecord*>(subcommand);
174         subcommandRecord->SetCheckRecordCallback(callback);
175     }
176 
177     // it need load some symbols and much more log
178     stdoutRecord.Start();
179     const auto startTime = std::chrono::steady_clock::now();
180     bool ret = Command::DispatchCommand(cmdString);
181     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
182         std::chrono::steady_clock::now() - startTime);
183     std::string stringOut = stdoutRecord.Stop();
184     if (expect) {
185         EXPECT_EQ(stringOut.find("Sample records:") != std::string::npos, true);
186     }
187     printf("run %" PRId64 " ms return %s(expect %s)\n", (uint64_t)costMs.count(), ret ? "true" : "false",
188            expect ? "true" : "false");
189     EXPECT_EQ(expect, ret);
190 }
191 
GetFileSize(const char * fileName)192 size_t SubCommandRecordTest::GetFileSize(const char* fileName)
193 {
194     if (fileName == nullptr) {
195         return 0;
196     }
197     struct stat statbuf;
198     if (stat(fileName, &statbuf) == -1) {
199         return 0;
200     }
201     size_t fileSize = statbuf.st_size;
202     return fileSize;
203 }
204 
CheckIntFromProcFile(const std::string & proc,int expect)205 static bool CheckIntFromProcFile(const std::string& proc, int expect)
206 {
207     int value = -1;
208     if (!ReadIntFromProcFile(proc, value)) {
209         return false;
210     }
211 
212     return value == expect;
213 }
214 
CheckJsonReport(const std::string & fileName,const std::string & symbolsFile,const int index=0)215 bool CheckJsonReport(const std::string& fileName, const std::string& symbolsFile, const int index = 0)
216 {
217     cJSON* root = ParseJson(fileName.c_str());
218     if (root == nullptr) {
219         return false;
220     }
221     auto list = cJSON_GetObjectItem(root, "processNameMap");
222     auto size = cJSON_GetArraySize(list);
223     bool find = false;
224     for (int i = 0; i < size; i++) {
225         auto item = cJSON_GetArrayItem(list, i);
226         if (std::string(item->valuestring).find(SubCommandRecordTest::testProcesses) != std::string::npos) {
227             find = true;
228             break;
229         }
230     }
231     if (!find) {
232         return false;
233     }
234     list = cJSON_GetObjectItem(root, "symbolsFileList");
235     size = cJSON_GetArraySize(list);
236     if (!symbolsFile.empty()) {
237         find = false;
238         for (int i = 0; i < size; i++) {
239             auto item = cJSON_GetArrayItem(list, i);
240             if (symbolsFile == item->valuestring) {
241                 find = true;
242                 break;
243             }
244         }
245         if (!find) {
246             return false;
247         }
248     }
249     auto listRecord = cJSON_GetObjectItem(root, "recordSampleInfo");
250     if (cJSON_GetArraySize(listRecord) <= 0) {
251         return false;
252     }
253     auto itemRecord = cJSON_GetArrayItem(listRecord, 0);
254     auto listProcesses = cJSON_GetObjectItem(itemRecord, "processes");
255     if (cJSON_GetArraySize(listProcesses) <= 0) {
256         return false;
257     }
258     auto itemProcesses = cJSON_GetArrayItem(listProcesses, index);
259     auto listThreads = cJSON_GetObjectItem(itemProcesses, "threads");
260     if (cJSON_GetArraySize(listThreads) <= 0) {
261         return false;
262     }
263     auto itemThreads = cJSON_GetArrayItem(listThreads, 0);
264     auto listLibs = cJSON_GetObjectItem(itemThreads, "libs");
265     if (cJSON_GetArraySize(listLibs) <= 0) {
266         return false;
267     }
268     auto itemCallOrder = cJSON_GetObjectItem(itemThreads, "CallOrder");
269     auto itemCallStack = cJSON_GetObjectItem(itemCallOrder, "callStack");
270     if (cJSON_GetArraySize(itemCallStack) <= 0) {
271         return false;
272     }
273     return true;
274 }
275 
276 // app package name
277 HWTEST_F(SubCommandRecordTest, PackageName, TestSize.Level0)
278 {
279     ForkAndRunTest("-d 2 ", true, true);
280 }
281 
282 // check app milliseconds
283 /**
284  * @tc.name: CheckAppMsMin
285  * @tc.desc: Test chkms minimum value
286  * @tc.type: FUNC
287  * @tc.require: issueI5R305
288  */
289 HWTEST_F(SubCommandRecordTest, CheckAppMsMin, TestSize.Level1)
290 {
291     ForkAndRunTest("-d 0.5 --chkms 1 ");
292 }
293 
294 /**
295  * @tc.name: CheckAppMsMinErr
296  * @tc.desc: Test chkms less than minimum value
297  * @tc.type: FUNC
298  * @tc.require: issueI5R305
299  */
300 HWTEST_F(SubCommandRecordTest, CheckAppMsMinErr, TestSize.Level3)
301 {
302     TestRecordCommand("-d 0.5 --chkms 0 ", false);
303 }
304 
305 /**
306  * @tc.name: CheckAppMsMax
307  * @tc.desc: Test chkms maximum value
308  * @tc.type: FUNC
309  * @tc.require: issueI5R305
310  */
311 HWTEST_F(SubCommandRecordTest, CheckAppMsMax, TestSize.Level1)
312 {
313     ForkAndRunTest("-d 0.5 --chkms 200 ");
314 }
315 
316 /**
317  * @tc.name: CheckAppMsMaxErr
318  * @tc.desc: Test chkms more than maximum value
319  * @tc.type: FUNC
320  * @tc.require: issueI5R305
321  */
322 HWTEST_F(SubCommandRecordTest, CheckAppMsMaxErr, TestSize.Level3)
323 {
324     TestRecordCommand("-d 0.5 --chkms 201 ", false);
325 }
326 
327 /**
328  * @tc.name: CheckAppMsInputErr
329  * @tc.desc: Test erro type of chkms
330  * @tc.type: FUNC
331  * @tc.require: issueI5R305
332  */
333 HWTEST_F(SubCommandRecordTest, CheckAppMsInputErr, TestSize.Level3)
334 {
335     TestRecordCommand("-d 0.5 --chkms abc ", false);
336 }
337 // stop seconds
338 HWTEST_F(SubCommandRecordTest, StopSecondsMin, TestSize.Level1)
339 {
340     ForkAndRunTest("-d 0.1 ");
341 }
342 
343 HWTEST_F(SubCommandRecordTest, StopSecondsMinErr, TestSize.Level2)
344 {
345     TestRecordCommand("-d 0.099 ", false);
346 }
347 
348 HWTEST_F(SubCommandRecordTest, StopSecondsMax, TestSize.Level3)
349 {
350     std::string opt = "-d 10000.0 ";
351     opt += " ls "; // because UT don't need wait so long
352     ForkAndRunTest(opt, true, false);
353 }
354 
355 HWTEST_F(SubCommandRecordTest, StopSecondsMaxErr, TestSize.Level2)
356 {
357     std::string opt = "-d 10000.1 ";
358     opt += " ";
359     TestRecordCommand(opt, false);
360 }
361 
362 HWTEST_F(SubCommandRecordTest, ReportCommand, TestSize.Level1)
363 {
364     std::shared_ptr<HiperfEventListener> eventListener = std::make_shared<HiperfEventListener>();
365     std::vector<ListenerRule> sysRules;
366     sysRules.emplace_back(OHOS::HiviewDFX::HiSysEvent::Domain::PROFILER, "HIPERF_USAGE", RuleType::WHOLE_WORD);
367     HiSysEventManager::AddListener(eventListener, sysRules);
368 
369     ForkAndRunTest("-d 2 -a ", true, false);
370 
371     std::this_thread::sleep_for(std::chrono::seconds(1));
372     HiSysEventManager::RemoveListener(eventListener);
373     std::shared_ptr<HiviewDFX::HiSysEventRecord> eventRecord = eventListener->GetLastEvent();
374     ASSERT_NE(eventRecord, nullptr);
375 
376     std::string value = "";
377     EXPECT_EQ(eventRecord->GetParamValue("MAIN_CMD", value), VALUE_PARSED_SUCCEED);
378     EXPECT_EQ(value, "record");
379 
380     EXPECT_EQ(eventRecord->GetParamValue("SUB_CMD", value), VALUE_PARSED_SUCCEED);
381     EXPECT_EQ(value, " record -d 2 -a");
382 
383     EXPECT_EQ(eventRecord->GetParamValue("CALLER", value), VALUE_PARSED_SUCCEED);
384     EXPECT_EQ(value, "./hiperf_unittest");
385 
386     EXPECT_EQ(eventRecord->GetParamValue("TARGET_PROCESS", value), VALUE_PARSED_SUCCEED);
387     EXPECT_EQ(value, "ALL");
388 
389     EXPECT_EQ(eventRecord->GetParamValue("ERROR_CODE", value), VALUE_PARSED_SUCCEED);
390     EXPECT_EQ(value, "0");
391 
392     EXPECT_EQ(eventRecord->GetParamValue("ERROR_MESSAGE", value), VALUE_PARSED_SUCCEED);
393     if (!value.empty()) {
394         EXPECT_EQ(value, "NO_ERR");
395     }
396 }
397 
398 // system wide
399 HWTEST_F(SubCommandRecordTest, SystemWide, TestSize.Level1)
400 {
401     ForkAndRunTest("-d 2 -a ", true, false);
402 }
403 
404 // trackedCommand_
405 HWTEST_F(SubCommandRecordTest, TrackedCommandErr, TestSize.Level3)
406 {
407     TestRecordCommand("-d 2 -a aa ", false, false);
408 }
409 
410 // --app and -p
411 HWTEST_F(SubCommandRecordTest, HasTargetErr, TestSize.Level3)
412 {
413     TestRecordCommand("--app test -p 123 -d 3 ", false, false);
414 }
415 
416 HWTEST_F(SubCommandRecordTest, HasTargetErr1, TestSize.Level3)
417 {
418     TestRecordCommand("-d 3 ", false, false);
419 }
420 
421 // exclude hiperf
422 HWTEST_F(SubCommandRecordTest, ExcludePerf, TestSize.Level3)
423 {
__anon21b1720a0102(const PerfEventRecord& record) 424     SubCommandRecord::CheckRecordCallBack callback = [](const PerfEventRecord& record) {
425         if (record.GetType() == PERF_RECORD_SAMPLE) {
426             const PerfRecordSample& recordSample = static_cast<const PerfRecordSample&>(record);
427             if (recordSample.data_.pid == getpid()) {
428                 _exit(1);
429             }
430         }
431     };
432     ForkAndRunTest("-d 2 -a --exclude-hiperf ", true, false, callback);
433 }
434 
435 HWTEST_F(SubCommandRecordTest, ExcludePerfErr, TestSize.Level2)
436 {
437     TestRecordCommand("-d 2 --exclude-hiperf ", false, true);
438 }
439 
440 // select cpu
441 HWTEST_F(SubCommandRecordTest, SelectCpu, TestSize.Level1)
442 {
__anon21b1720a0202(const PerfEventRecord& record) 443     SubCommandRecord::CheckRecordCallBack callback = [](const PerfEventRecord& record) {
444         if (record.GetType() == PERF_RECORD_SAMPLE) {
445             const PerfRecordSample& recordSample = static_cast<const PerfRecordSample&>(record);
446             if (recordSample.data_.cpu != 0) {
447                 _exit(1);
448             }
449         }
450     };
451     ForkAndRunTest("-d 2 -c 0 ", true, true, callback);
452 }
453 
454 HWTEST_F(SubCommandRecordTest, SelectCpuMulti, TestSize.Level0)
455 {
456     int maxCpuid = sysconf(_SC_NPROCESSORS_CONF);
457     std::string opt = "-d 2 -e sw-task-clock -c ";
458     for (int i = 0; i < maxCpuid; i++) {
459         opt += std::to_string(i);
460         opt += ",";
461     }
462     opt.pop_back();
463     opt += " ";
464 
__anon21b1720a0302(const PerfEventRecord& record) 465     SubCommandRecord::CheckRecordCallBack callback = [maxCpuid](const PerfEventRecord& record) {
466         if (record.GetType() == PERF_RECORD_SAMPLE) {
467             const PerfRecordSample& recordSample = static_cast<const PerfRecordSample&>(record);
468             if (recordSample.data_.cpu >= maxCpuid) {
469                 _exit(1);
470             }
471         }
472     };
473     ForkAndRunTest(opt, true, true, callback);
474 }
475 
476 HWTEST_F(SubCommandRecordTest, SelectCpuMinErr, TestSize.Level2)
477 {
478     TestRecordCommand("-d 2 -c -1 ", false);
479 }
480 
481 HWTEST_F(SubCommandRecordTest, SelectCpuMaxErr, TestSize.Level2)
482 {
483     int maxCpuid = sysconf(_SC_NPROCESSORS_CONF);
484     std::string opt = "-d 2 -c ";
485     opt += std::to_string(maxCpuid);
486     opt += " ";
487     TestRecordCommand(opt, false);
488 }
489 
490 HWTEST_F(SubCommandRecordTest, SelectCpuInputErr, TestSize.Level3)
491 {
492     TestRecordCommand("-d 2 -c abc ", false);
493 }
494 
495 // --control
496 HWTEST_F(SubCommandRecordTest, CheckControlErr, TestSize.Level3)
497 {
498     TestRecordCommand("-a --control st", false, false);
499 }
500 
501 // cpu percent
502 HWTEST_F(SubCommandRecordTest, CpuLimitMin, TestSize.Level1)
503 {
504     ForkAndRunTest("-d 2 --cpu-limit 1 ");
505     EXPECT_EQ(CheckIntFromProcFile(PERF_CPU_TIME_MAX_PERCENT, 1), true);
506 }
507 
508 HWTEST_F(SubCommandRecordTest, CpuLimitErr, TestSize.Level3)
509 {
510     TestRecordCommand("-d 2 --cpu-limit 0 ", false);
511 }
512 
513 HWTEST_F(SubCommandRecordTest, CpuLimitMax, TestSize.Level1)
514 {
515     ForkAndRunTest("-d 2 --cpu-limit 100 ");
516     EXPECT_EQ(CheckIntFromProcFile(PERF_CPU_TIME_MAX_PERCENT, 100), true);
517 }
518 
519 HWTEST_F(SubCommandRecordTest, CpuLimitMaxErr, TestSize.Level2)
520 {
521     TestRecordCommand("-d 2 --cpu-limit 101 ", false);
522 }
523 
524 HWTEST_F(SubCommandRecordTest, CpuLimitInputErr, TestSize.Level2)
525 {
526     TestRecordCommand("-d 2 --cpu-limit abc ", false);
527 }
528 
529 // frequency
530 HWTEST_F(SubCommandRecordTest, FrequncyMin, TestSize.Level1)
531 {
532     ForkAndRunTest("-d 2 -f 1 ");
533 }
534 
535 HWTEST_F(SubCommandRecordTest, FrequncyMinErr, TestSize.Level2)
536 {
537     TestRecordCommand("-d 2 -f 0 ", false);
538 }
539 
540 HWTEST_F(SubCommandRecordTest, FrequncyMax, TestSize.Level3)
541 {
542     ForkAndRunTest("-d 2 -f 100000 ");
543 }
544 
545 HWTEST_F(SubCommandRecordTest, FrequncyMaxErr, TestSize.Level2)
546 {
547     TestRecordCommand("-d 2 -f 100001 ", false);
548 }
549 
550 HWTEST_F(SubCommandRecordTest, FrequncyInputErr, TestSize.Level3)
551 {
552     TestRecordCommand("-d 2 -f abc ", false);
553 }
554 
555 // period
556 HWTEST_F(SubCommandRecordTest, PeriodMin, TestSize.Level1)
557 {
558     ForkAndRunTest("-d 2 --period 1 ");
559 }
560 
561 HWTEST_F(SubCommandRecordTest, PeriodMinErr, TestSize.Level2)
562 {
563     TestRecordCommand("-d 2 --period 0 ", false);
564 }
565 
566 HWTEST_F(SubCommandRecordTest, PeriodMax, TestSize.Level1)
567 {
568     std::string opt = "-d 2 --period ";
569     opt += std::to_string(INT_MAX);
570     opt += " ";
571     ForkAndRunTest(opt);
572 }
573 
574 HWTEST_F(SubCommandRecordTest, PeriodMaxErr, TestSize.Level2)
575 {
576     std::string opt = "-d 2 --period ";
577     uint32_t value = static_cast<uint32_t>(INT_MAX) + 1;
578     opt += std::to_string(value);
579     opt += " ";
580     TestRecordCommand(opt, false);
581 }
582 
583 HWTEST_F(SubCommandRecordTest, PeriodInputErr, TestSize.Level2)
584 {
585     TestRecordCommand("-d 2 --period abc ", false);
586 }
587 
588 HWTEST_F(SubCommandRecordTest, PeriodAndFrequncyConflict, TestSize.Level2)
589 {
590     TestRecordCommand("-d 2 -f 2000 --period 10 ", false);
591 }
592 
TestEvents(std::string & opt,std::string & uk,bool isFork)593 void SubCommandRecordTest::TestEvents(std::string &opt, std::string &uk, bool isFork)
594 {
595     PerfEvents perfEvents;
596     perfEvents.SetHM(IsHM());
597     for (auto type : TYPE_CONFIGS) {
598         auto configs = perfEvents.GetSupportEvents(type.first);
599         if (configs.empty()) {
600             continue;
601         }
602 
603         const int MAX_TESTEVENT = 5;
604         int testEventCount = MAX_TESTEVENT;
605         std::string cmdline = opt;
606         for (auto config : configs) {
607             if (testEventCount <= 0) {
608                 break;
609             }
610             cmdline += config.second;
611             cmdline += uk;
612             cmdline += ",";
613             testEventCount--;
614         }
615         cmdline.pop_back(); // remove the last ','
616         if (isFork) {
617             ForkAndRunTest(cmdline);
618         } else {
619             TestRecordCommand(cmdline);
620         }
621         TearDown();
622         SetUp();
623     }
624 }
625 
626 // select events
627 HWTEST_F(SubCommandRecordTest, SelectEvents, TestSize.Level0)
628 {
629     std::string opt = "-d 2 -c 0 -e ";
630     std::string uk = "";
631     TestEvents(opt, uk);
632 }
633 
634 HWTEST_F(SubCommandRecordTest, SelectEventsUser, TestSize.Level1)
635 {
636     std::string opt = "-d 2 -c 0 -e ";
637     std::string uk = ":u";
638     TestEvents(opt, uk);
639 }
640 
641 HWTEST_F(SubCommandRecordTest, SelectEventsKernel, TestSize.Level1)
642 {
643     std::string opt = "-d 2 -c 0 -e ";
644     std::string uk = ":k";
645     TestEvents(opt, uk);
646 }
647 
648 HWTEST_F(SubCommandRecordTest, SelectEventsKernel_2, TestSize.Level1)
649 {
650     std::string opt = "-d 2 -c 0 -e ";
651     std::string uk = ":k";
652     TestEvents(opt, uk, false);
653 }
654 
655 HWTEST_F(SubCommandRecordTest, SelectEventsErr, TestSize.Level3)
656 {
657     ForkAndRunTest("-d 2 -c 0 -e what ", false);
658 }
659 
660 // select group events
661 HWTEST_F(SubCommandRecordTest, GroupEvents, TestSize.Level1)
662 {
663     std::string opt = "-d 2 -c 0 -g ";
664     std::string uk = "";
665     TestEvents(opt, uk);
666 }
667 
668 HWTEST_F(SubCommandRecordTest, GroupEventsUser, TestSize.Level1)
669 {
670     std::string opt = "-d 2 -c 0 -g ";
671     std::string uk = ":u";
672     TestEvents(opt, uk);
673 }
674 
675 HWTEST_F(SubCommandRecordTest, GroupEventsKernal, TestSize.Level1)
676 {
677     std::string opt = "-d 2 -c 0 -g ";
678     std::string uk = ":k";
679     TestEvents(opt, uk);
680 }
681 
682 HWTEST_F(SubCommandRecordTest, GroupEventsErr, TestSize.Level2)
683 {
684     ForkAndRunTest("-d 2 -c 0 -g what ", false);
685 }
686 
687 HWTEST_F(SubCommandRecordTest, NoInherit, TestSize.Level1)
688 {
689     ForkAndRunTest("-d 2 --no-inherit ");
690 }
691 
692 // select pid
693 HWTEST_F(SubCommandRecordTest, SelectPid, TestSize.Level1)
694 {
695     ForkAndRunTest("-d 2 -p 1 ", true, false);
696 }
697 
698 HWTEST_F(SubCommandRecordTest, KernelSymbols, TestSize.Level1)
699 {
700     TestRecordCommand("-d 2 -p 2 -s dwarf ", true, false);
701 }
702 
703 HWTEST_F(SubCommandRecordTest, SelectPidMulti, TestSize.Level0)
704 {
705     ForkAndRunTest("-d 2 -p 1,2 ", true, false);
706 }
707 
708 HWTEST_F(SubCommandRecordTest, SelectPidMinErr, TestSize.Level2)
709 {
710     TestRecordCommand("-d 2 -p 0 ", false, false);
711 }
712 
713 HWTEST_F(SubCommandRecordTest, SelectPidMinErr1, TestSize.Level3)
714 {
715     TestRecordCommand("-d 2 -p -1 ", false, false);
716 }
717 
718 HWTEST_F(SubCommandRecordTest, SelectPidErr, TestSize.Level2)
719 {
720     TestRecordCommand("-d 2 -p 99999999 ", false, false);
721 }
722 
723 HWTEST_F(SubCommandRecordTest, SelectPidInputErr, TestSize.Level2)
724 {
725     TestRecordCommand("-d 2 -p abc ", false, false);
726 }
727 
728 HWTEST_F(SubCommandRecordTest, SelectPidInputConflict, TestSize.Level3)
729 {
730     ForkAndRunTest("-d 2 -a -p 1 ", false, false);
731 }
732 
733 // select tid
734 HWTEST_F(SubCommandRecordTest, SelectTid, TestSize.Level1)
735 {
736     ForkAndRunTest("-d 2 -t 1 ", true, false);
737 }
738 
739 HWTEST_F(SubCommandRecordTest, SelectTidMulti, TestSize.Level0)
740 {
741     ForkAndRunTest("-d 2 -t 1,2 ", true, false);
742 }
743 
744 HWTEST_F(SubCommandRecordTest, SelectTidMinErr, TestSize.Level3)
745 {
746     TestRecordCommand("-d 2 -t 0 ", false, false);
747 }
748 
749 HWTEST_F(SubCommandRecordTest, SelectTidErr, TestSize.Level3)
750 {
751     TestRecordCommand("-d 2 -t 99999999 ", false, false);
752 }
753 
754 HWTEST_F(SubCommandRecordTest, SelectTidInputErr, TestSize.Level3)
755 {
756     TestRecordCommand("-d 2 -t abc ", false, false);
757 }
758 
759 // cpu off
760 HWTEST_F(SubCommandRecordTest, CpuOff, TestSize.Level1)
761 {
762     ForkAndRunTest("-d 2 --offcpu -o /data/local/tmp/offcpu_perf.data");
763 }
764 
765 HWTEST_F(SubCommandRecordTest, BranchFilterInputErr, TestSize.Level3)
766 {
767     TestRecordCommand("-d 2 -j what ", false);
768 }
769 
770 HWTEST_F(SubCommandRecordTest, BranchFilterInputMoreErr, TestSize.Level3)
771 {
772     TestRecordCommand("-d 2 -j any,n ", false);
773 }
774 
775 // call stack
776 HWTEST_F(SubCommandRecordTest, CallStackFp, TestSize.Level0)
777 {
778     ForkAndRunTest("-d 2 --call-stack fp ");
779     TearDown();
780     SetUp();
781     ForkAndRunTest("-d 2 -s fp ");
782 }
783 
784 HWTEST_F(SubCommandRecordTest, CallStackFpInputMoreErr, TestSize.Level2)
785 {
786     TestRecordCommand("-d 2 --call-stack fp,abc ", false);
787     TearDown();
788     SetUp();
789     TestRecordCommand("-d 2 -s fp,abc ", false);
790 }
791 
792 HWTEST_F(SubCommandRecordTest, CallStackInputErr, TestSize.Level2)
793 {
794     TestRecordCommand("-d 2 --call-stack what ", false);
795     TearDown();
796     SetUp();
797     TestRecordCommand("-d 2 -s what ", false);
798 }
799 
800 HWTEST_F(SubCommandRecordTest, CallStackDwarfSizeMin, TestSize.Level2)
801 {
802     // it will cause some crash in -fprofile-arcs and -ftest-coverage
803     // we will fix it latter
804     ForkAndRunTest("-d 2 --call-stack dwarf,8 ");
805     TearDown();
806     SetUp();
807     ForkAndRunTest("-d 2 -s dwarf,8 ");
808 }
809 
810 HWTEST_F(SubCommandRecordTest, CallStackDwarfSizeMinErr, TestSize.Level2)
811 {
812     TestRecordCommand("-d 2 --call-stack dwarf,7 ", false);
813     TearDown();
814     SetUp();
815     TestRecordCommand("-d 2 -s dwarf,7 ", false);
816 }
817 
818 HWTEST_F(SubCommandRecordTest, CallStackDwarfSizeMax, TestSize.Level1)
819 {
820     ForkAndRunTest("-d 2 --call-stack dwarf,65528 ");
821     TearDown();
822     SetUp();
823     ForkAndRunTest("-d 2 -s dwarf,65528 ");
824 }
825 
826 HWTEST_F(SubCommandRecordTest, CallStackDwarfSizeMaxErr, TestSize.Level2)
827 {
828     TestRecordCommand("-d 2 --call-stack dwarf,65529 ", false);
829     TearDown();
830     SetUp();
831     TestRecordCommand("-d 2 -s dwarf,65529 ", false);
832 }
833 
834 HWTEST_F(SubCommandRecordTest, CallStackDwarfSizeErr, TestSize.Level2)
835 {
836     TestRecordCommand("-d 2 --call-stack dwarf,15 ", false);
837     TearDown();
838     SetUp();
839     TestRecordCommand("-d 2 -s dwarf,15 ", false);
840 }
841 
842 HWTEST_F(SubCommandRecordTest, CallStackDwarfSizeInputErr, TestSize.Level2)
843 {
844     TestRecordCommand("-d 2 --call-stack dwarf,abc ", false);
845     TearDown();
846     SetUp();
847     TestRecordCommand("-d 2 -s dwarf,abc ", false);
848 }
849 
850 HWTEST_F(SubCommandRecordTest, CallStackDwarfSizeInputMoreErr, TestSize.Level3)
851 {
852     TestRecordCommand("-d 2 --call-stack dwarf,16,32 ", false);
853     TearDown();
854     SetUp();
855     TestRecordCommand("-d 2 -s dwarf,16,32 ", false);
856 }
857 
858 HWTEST_F(SubCommandRecordTest, CallStackUsageErr, TestSize.Level3)
859 {
860     TestRecordCommand("-d 2 -s abc --call-stack bcd", false);
861 }
862 
863 // unwind
864 HWTEST_F(SubCommandRecordTest, DlayUnwind, TestSize.Level1)
865 {
866     ForkAndRunTest("-d 2 -s dwarf,16 --delay-unwind ");
867 }
868 
869 HWTEST_F(SubCommandRecordTest, DisableUnwind, TestSize.Level1)
870 {
871     ForkAndRunTest("-d 2 -s dwarf,16 --disable-unwind ");
872 }
873 
874 HWTEST_F(SubCommandRecordTest, DisableCallstackMerge, TestSize.Level1)
875 {
876     ForkAndRunTest("-d 2 -s dwarf,16 --disable-callstack-expand ");
877 }
878 
879 // symbol dir
880 HWTEST_F(SubCommandRecordTest, SymbolDir, TestSize.Level1)
881 {
882     ForkAndRunTest("-d 2 --symbol-dir ./ ");
883 }
884 
885 HWTEST_F(SubCommandRecordTest, SymbolDirErr, TestSize.Level2)
886 {
887     TestRecordCommand("-d 2 --symbol-dir where ", false);
888 }
889 
890 // clock id
891 HWTEST_F(SubCommandRecordTest, ClockIdMonotonic, TestSize.Level1)
892 {
893     ForkAndRunTest("-d 2 --clockid monotonic ");
894 }
895 
896 HWTEST_F(SubCommandRecordTest, ClockIdMonotonicRaw, TestSize.Level1)
897 {
898     ForkAndRunTest("-d 2 --clockid monotonic_raw ");
899 }
900 
901 HWTEST_F(SubCommandRecordTest, ClockIdBoottime, TestSize.Level1)
902 {
903     ForkAndRunTest("-c 0 -d 2 -e sw-task-clock --clockid boottime ");
904 }
905 
906 HWTEST_F(SubCommandRecordTest, ClockIdRealtime, TestSize.Level1)
907 {
908     ForkAndRunTest("-c 0 -d 2 -e sw-task-clock --clockid realtime ");
909 }
910 
911 HWTEST_F(SubCommandRecordTest, ClockIdClockTai, TestSize.Level1)
912 {
913     ForkAndRunTest("-c 0 -d 2 -e sw-task-clock --clockid clock_tai ");
914 }
915 
916 HWTEST_F(SubCommandRecordTest, ClockIdInputErr, TestSize.Level2)
917 {
918     TestRecordCommand("-c 0 -d 2 --clockid what ", false);
919 }
920 
921 // mmap pages
922 HWTEST_F(SubCommandRecordTest, MmapPagesPower2Err, TestSize.Level3)
923 {
924     TestRecordCommand("-d 2 -m 101 ", false);
925 }
926 
927 HWTEST_F(SubCommandRecordTest, MmapPagesMin, TestSize.Level2)
928 {
929     ForkAndRunTest("-d 2 -m 2 ");
930 }
931 
932 HWTEST_F(SubCommandRecordTest, MmapPagesMinErr, TestSize.Level2)
933 {
934     TestRecordCommand("-d 2 -m 1 ", false);
935 }
936 
937 HWTEST_F(SubCommandRecordTest, MmapPagesMax, TestSize.Level1)
938 {
939     ForkAndRunTest("-d 2 -m 1024 ");
940 }
941 
942 HWTEST_F(SubCommandRecordTest, MmapPagesMaxErr, TestSize.Level2)
943 {
944     TestRecordCommand("-d 2 -m 1025 ", false);
945 }
946 
947 HWTEST_F(SubCommandRecordTest, MmapPagesInputErr, TestSize.Level2)
948 {
949     TestRecordCommand("-d 2 -m abc ", false);
950 }
951 
952 // output file name
953 HWTEST_F(SubCommandRecordTest, OutputFileName, TestSize.Level2)
954 {
955     ForkAndRunTest("-d 2 -o /data/local/tmp/output.perf.data ");
956 }
957 
958 HWTEST_F(SubCommandRecordTest, OutputFileNameErr, TestSize.Level2)
959 {
960     TestRecordCommand("-d 2 -o nopath/output.perf.data ", false);
961 }
962 
963 // data size limit
964 HWTEST_F(SubCommandRecordTest, DataLimit, TestSize.Level2)
965 {
966     ForkAndRunTest("-d 2 --data-limit 1K ");
967     TearDown();
968     SetUp();
969     ForkAndRunTest("-d 2 --data-limit 1M ");
970     TearDown();
971     SetUp();
972     ForkAndRunTest("-d 2 --data-limit 1G ");
973 }
974 
975 HWTEST_F(SubCommandRecordTest, DataLimit1, TestSize.Level2)
976 {
977     ForkAndRunTest("-a --data-limit 1K ", true, false);
978 }
979 
980 HWTEST_F(SubCommandRecordTest, DataLimitErr, TestSize.Level2)
981 {
982     TestRecordCommand("-d 2 --data-limit 10A ", false);
983     TearDown();
984     SetUp();
985     TestRecordCommand("-d 2 --data-limit 0G ", false);
986 }
987 
988 HWTEST_F(SubCommandRecordTest, RecordCompress, TestSize.Level1)
989 {
990     ForkAndRunTest("-d 2 -z -o /data/local/tmp/perf.data.tar.gz");
991 }
992 
993 HWTEST_F(SubCommandRecordTest, Verbose, TestSize.Level2)
994 {
995     ForkAndRunTest("-d 2 --verbose ");
996 }
997 
998 HWTEST_F(SubCommandRecordTest, DumpOptions, TestSize.Level2)
999 {
1000     StdoutRecord stdoutRecord;
1001     stdoutRecord.Start();
1002     SubCommandRecord cmd;
1003     cmd.DumpOptions();
1004     std::string stringOut = stdoutRecord.Stop();
1005     EXPECT_TRUE(stringOut.find("cpuPercent:	25") != std::string::npos);
1006     EXPECT_TRUE(stringOut.find("mmapPages_:	1024") != std::string::npos);
1007 }
1008 
1009 /**
1010  * @tc.name: FileSizeOnFrequency100_DWARF_SYSTEM
1011  * @tc.desc: Test size of file generated under system wide frequency 100 and dwarf unwind
1012  * @tc.type: FUNC
1013  */
1014 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency100_DWARF_SYSTEM, TestSize.Level2)
1015 {
1016     ForkAndRunTest("-d 10 -a -f 100 -s dwarf", true, false);
1017     std::string fileName = TEST_FILE;
1018     size_t fileSize = GetFileSize(fileName.c_str());
1019     EXPECT_GT(fileSize, 0);
1020     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1021         {"magic:"}), true);
1022 }
1023 
1024 /**
1025  * @tc.name: FileSizeOnFrequency500_DWARF_SYSTEM
1026  * @tc.desc: Test size of file generated under system wide frequency 500 and dwarf unwind
1027  * @tc.type: FUNC
1028  */
1029 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency500_DWARF_SYSTEM, TestSize.Level2)
1030 {
1031     ForkAndRunTest("-d 10 -a -f 500 -s dwarf", true, false);
1032     std::string fileName = TEST_FILE;
1033     size_t fileSize = GetFileSize(fileName.c_str());
1034     EXPECT_GT(fileSize, 0);
1035     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1036         {"magic:"}), true);
1037 }
1038 
1039 /**
1040  * @tc.name: FileSizeOnFrequency1000_DWARF_SYSTEM
1041  * @tc.desc: Test size of file generated under system wide frequency 1000 and dwarf unwind
1042  * @tc.type: FUNC
1043  */
1044 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency1000_DWARF_SYSTEM, TestSize.Level2)
1045 {
1046     ForkAndRunTest("-d 10 -a -f 1000 -s dwarf", true, false);
1047     std::string fileName = TEST_FILE;
1048     size_t fileSize = GetFileSize(fileName.c_str());
1049     EXPECT_GT(fileSize, 0);
1050     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1051         {"magic:"}), true);
1052 }
1053 
1054 /**
1055  * @tc.name: FileSizeOnFrequency2000_DWARF_SYSTEM
1056  * @tc.desc: Test size of file generated under system wide frequency 2000 and dwarf unwind
1057  * @tc.type: FUNC
1058  */
1059 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency2000_DWARF_SYSTEM, TestSize.Level2)
1060 {
1061     ForkAndRunTest("-d 10 -a -f 2000 -s dwarf", true, false);
1062     std::string fileName = TEST_FILE;
1063     size_t fileSize = GetFileSize(fileName.c_str());
1064     EXPECT_GT(fileSize, 0);
1065     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1066         {"magic:"}), true);
1067 }
1068 
1069 /**
1070  * @tc.name: FileSizeOnFrequency4000_DWARF_SYSTEM
1071  * @tc.desc: Test size of file generated under system wide frequency 4000 and dwarf unwind
1072  * @tc.type: FUNC
1073  */
1074 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency4000_DWARF_SYSTEM, TestSize.Level0)
1075 {
1076     ForkAndRunTest("-d 10 -a -f 4000 -s dwarf", true, false);
1077     std::string fileName = TEST_FILE;
1078     size_t fileSize = GetFileSize(fileName.c_str());
1079     EXPECT_GT(fileSize, 0);
1080     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1081         {"magic:"}), true);
1082 }
1083 
1084 /**
1085  * @tc.name: FileSizeOnFrequency8000_DWARF_SYSTEM
1086  * @tc.desc: Test size of file generated under system wide frequency 8000 and dwarf unwind
1087  * @tc.type: FUNC
1088  */
1089 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency8000_DWARF_SYSTEM, TestSize.Level2)
1090 {
1091     ForkAndRunTest("-d 10 -a -f 8000 -s dwarf", true, false);
1092     std::string fileName = TEST_FILE;
1093     size_t fileSize = GetFileSize(fileName.c_str());
1094     EXPECT_GT(fileSize, 0);
1095     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1096         {"magic:"}), true);
1097 }
1098 
1099 /**
1100  * @tc.name: FileSizeOnFrequency100_FP_SYSTEM
1101  * @tc.desc: Test size of file generated under system wide frequency 100 and fp unwind
1102  * @tc.type: FUNC
1103  */
1104 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency100_FP_SYSTEM, TestSize.Level2)
1105 {
1106     ForkAndRunTest("-d 10 -a -f 100 -s fp", true, false);
1107     std::string fileName = TEST_FILE;
1108     size_t fileSize = GetFileSize(fileName.c_str());
1109     EXPECT_GT(fileSize, 0);
1110     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1111         {"magic:"}), true);
1112 }
1113 
1114 /**
1115  * @tc.name: FileSizeOnFrequency500_FP_SYSTEM
1116  * @tc.desc: Test size of file generated under system wide frequency 500 and fp unwind
1117  * @tc.type: FUNC
1118  */
1119 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency500_FP_SYSTEM, TestSize.Level2)
1120 {
1121     ForkAndRunTest("-d 10 -a -f 500 -s fp", true, false);
1122     std::string fileName = TEST_FILE;
1123     size_t fileSize = GetFileSize(fileName.c_str());
1124     EXPECT_GT(fileSize, 0);
1125     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1126         {"magic:"}), true);
1127 }
1128 
1129 /**
1130  * @tc.name: FileSizeOnFrequency1000_FP_SYSTEM
1131  * @tc.desc: Test size of file generated under system wide frequency 1000 and fp unwind
1132  * @tc.type: FUNC
1133  */
1134 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency1000_FP_SYSTEM, TestSize.Level2)
1135 {
1136     ForkAndRunTest("-d 10 -a -f 1000 -s fp", true, false);
1137     std::string fileName = TEST_FILE;
1138     size_t fileSize = GetFileSize(fileName.c_str());
1139     EXPECT_GT(fileSize, 0);
1140     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1141         {"magic:"}), true);
1142 }
1143 
1144 /**
1145  * @tc.name: FileSizeOnFrequency2000_FP_SYSTEM
1146  * @tc.desc: Test size of file generated under system wide frequency 2000 and fp unwind
1147  * @tc.type: FUNC
1148  */
1149 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency2000_FP_SYSTEM, TestSize.Level2)
1150 {
1151     ForkAndRunTest("-d 10 -a -f 2000 -s fp", true, false);
1152     std::string fileName = TEST_FILE;
1153     size_t fileSize = GetFileSize(fileName.c_str());
1154     EXPECT_GT(fileSize, 0);
1155     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1156         {"magic:"}), true);
1157 }
1158 
1159 /**
1160  * @tc.name: FileSizeOnFrequency4000_FP_SYSTEM
1161  * @tc.desc: Test size of file generated under system wide frequency 4000 and fp unwind
1162  * @tc.type: FUNC
1163  */
1164 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency4000_FP_SYSTEM, TestSize.Level0)
1165 {
1166     ForkAndRunTest("-d 10 -a -f 4000 -s fp", true, false);
1167     std::string fileName = TEST_FILE;
1168     size_t fileSize = GetFileSize(fileName.c_str());
1169     EXPECT_GT(fileSize, 0);
1170     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1171         {"magic:"}), true);
1172 }
1173 
1174 /**
1175  * @tc.name: FileSizeOnFrequency8000_FP_SYSTEM
1176  * @tc.desc: Test size of file generated under system wide frequency 8000 and fp unwind
1177  * @tc.type: FUNC
1178  */
1179 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency8000_FP_SYSTEM, TestSize.Level2)
1180 {
1181     ForkAndRunTest("-d 10 -a -f 8000 -s fp", true, false);
1182     std::string fileName = TEST_FILE;
1183     size_t fileSize = GetFileSize(fileName.c_str());
1184     EXPECT_GT(fileSize, 0);
1185     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1186         {"magic:"}), true);
1187 }
1188 
1189 /**
1190  * @tc.name: FileSizeOnFrequency100_DWARF_PROCESS
1191  * @tc.desc: Test size of file generated under one process frequency 100 and dwarf unwind
1192  * @tc.type: FUNC
1193  */
1194 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency100_DWARF_PROCESS, TestSize.Level2)
1195 {
1196     ForkAndRunTest("-d 10 -f 100 -s dwarf", true, true);
1197     std::string fileName = TEST_FILE;
1198     size_t fileSize = GetFileSize(fileName.c_str());
1199     EXPECT_GT(fileSize, 0);
1200     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1201         {"magic:"}), true);
1202 }
1203 
1204 /**
1205  * @tc.name: FileSizeOnFrequency500_DWARF_PROCESS
1206  * @tc.desc: Test size of file generated under one process frequency 500 and dwarf unwind
1207  * @tc.type: FUNC
1208  */
1209 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency500_DWARF_PROCESS, TestSize.Level2)
1210 {
1211     ForkAndRunTest("-d 10 -f 500 -s dwarf", true, true);
1212     std::string fileName = TEST_FILE;
1213     size_t fileSize = GetFileSize(fileName.c_str());
1214     EXPECT_GT(fileSize, 0);
1215     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1216         {"magic:"}), true);
1217 }
1218 
1219 /**
1220  * @tc.name: FileSizeOnFrequency1000_DWARF_PROCESS
1221  * @tc.desc: Test size of file generated under one process frequency 1000 and dwarf unwind
1222  * @tc.type: FUNC
1223  */
1224 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency1000_DWARF_PROCESS, TestSize.Level2)
1225 {
1226     ForkAndRunTest("-d 10 -f 1000 -s dwarf", true, true);
1227     std::string fileName = TEST_FILE;
1228     size_t fileSize = GetFileSize(fileName.c_str());
1229     EXPECT_GT(fileSize, 0);
1230     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1231         {"magic:"}), true);
1232 }
1233 
1234 /**
1235  * @tc.name: FileSizeOnFrequency2000_DWARF_PROCESS
1236  * @tc.desc: Test size of file generated under one process frequency 2000 and dwarf unwind
1237  * @tc.type: FUNC
1238  */
1239 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency2000_DWARF_PROCESS, TestSize.Level2)
1240 {
1241     ForkAndRunTest("-d 10 -f 2000 -s dwarf", true, true);
1242     std::string fileName = TEST_FILE;
1243     size_t fileSize = GetFileSize(fileName.c_str());
1244     EXPECT_GT(fileSize, 0);
1245     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1246         {"magic:"}), true);
1247 }
1248 
1249 /**
1250  * @tc.name: FileSizeOnFrequency4000_DWARF_PROCESS
1251  * @tc.desc: Test size of file generated under one process frequency 4000 and dwarf unwind
1252  * @tc.type: FUNC
1253  */
1254 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency4000_DWARF_PROCESS, TestSize.Level0)
1255 {
1256     ForkAndRunTest("-d 10 -f 4000 -s dwarf", true, true);
1257     std::string fileName = TEST_FILE;
1258     size_t fileSize = GetFileSize(fileName.c_str());
1259     EXPECT_GT(fileSize, 0);
1260     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1261         {"magic:"}), true);
1262 }
1263 
1264 /**
1265  * @tc.name: FileSizeOnFrequency8000_DWARF_PROCESS
1266  * @tc.desc: Test size of file generated under one process frequency 8000 and dwarf unwind
1267  * @tc.type: FUNC
1268  */
1269 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency8000_DWARF_PROCESS, TestSize.Level2)
1270 {
1271     ForkAndRunTest("-d 10 -f 8000 -s dwarf", true, true);
1272     std::string fileName = TEST_FILE;
1273     size_t fileSize = GetFileSize(fileName.c_str());
1274     EXPECT_GT(fileSize, 0);
1275     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1276         {"magic:"}), true);
1277 }
1278 
1279 /**
1280  * @tc.name: FileSizeOnFrequency100_FP_PROCESS
1281  * @tc.desc: Test size of file generated under one process frequency 100 and fp unwind
1282  * @tc.type: FUNC
1283  */
1284 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency100_FP_PROCESS, TestSize.Level2)
1285 {
1286     ForkAndRunTest("-d 10 -f 100 -s fp", true, true);
1287     std::string fileName = TEST_FILE;
1288     size_t fileSize = GetFileSize(fileName.c_str());
1289     EXPECT_GT(fileSize, 0);
1290     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1291         {"magic:"}), true);
1292 }
1293 
1294 /**
1295  * @tc.name: FileSizeOnFrequency500_FP_PROCESS
1296  * @tc.desc: Test size of file generated under one process frequency 500 and fp unwind
1297  * @tc.type: FUNC
1298  */
1299 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency500_FP_PROCESS, TestSize.Level2)
1300 {
1301     ForkAndRunTest("-d 10 -f 500 -s fp", true, true);
1302     std::string fileName = TEST_FILE;
1303     size_t fileSize = GetFileSize(fileName.c_str());
1304     EXPECT_GT(fileSize, 0);
1305     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1306         {"magic:"}), true);
1307 }
1308 
1309 /**
1310  * @tc.name: FileSizeOnFrequency1000_FP_PROCESS
1311  * @tc.desc: Test size of file generated under one process frequency 1000 and fp unwind
1312  * @tc.type: FUNC
1313  */
1314 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency1000_FP_PROCESS, TestSize.Level2)
1315 {
1316     ForkAndRunTest("-d 10 -f 1000 -s fp", true, true);
1317     std::string fileName = TEST_FILE;
1318     size_t fileSize = GetFileSize(fileName.c_str());
1319     EXPECT_GT(fileSize, 0);
1320     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1321         {"magic:"}), true);
1322 }
1323 
1324 /**
1325  * @tc.name: FileSizeOnFrequency2000_FP_PROCESS
1326  * @tc.desc: Test size of file generated under one process frequency 2000 and fp unwind
1327  * @tc.type: FUNC
1328  */
1329 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency2000_FP_PROCESS, TestSize.Level2)
1330 {
1331     ForkAndRunTest("-d 10 -f 2000 -s fp", true, true);
1332     std::string fileName = TEST_FILE;
1333     size_t fileSize = GetFileSize(fileName.c_str());
1334     EXPECT_GT(fileSize, 0);
1335     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1336         {"magic:"}), true);
1337 }
1338 
1339 /**
1340  * @tc.name: FileSizeOnFrequency4000_FP_PROCESS
1341  * @tc.desc: Test size of file generated under one process frequency 4000 and fp unwind
1342  * @tc.type: FUNC
1343  */
1344 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency4000_FP_PROCESS, TestSize.Level0)
1345 {
1346     ForkAndRunTest("-d 10 -f 4000 -s fp", true, true);
1347     std::string fileName = TEST_FILE;
1348     size_t fileSize = GetFileSize(fileName.c_str());
1349     EXPECT_GT(fileSize, 0);
1350     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1351         {"magic:"}), true);
1352 }
1353 
1354 /**
1355  * @tc.name: FileSizeOnFrequency8000_FP_PROCESS
1356  * @tc.desc: Test size of file generated under one process frequency 8000 and fp unwind
1357  * @tc.type: FUNC
1358  */
1359 HWTEST_F(SubCommandRecordTest, FileSizeOnFrequency8000_FP_PROCESS, TestSize.Level2)
1360 {
1361     ForkAndRunTest("-d 10 -f 8000 -s fp", true, true);
1362     std::string fileName = TEST_FILE;
1363     size_t fileSize = GetFileSize(fileName.c_str());
1364     EXPECT_GT(fileSize, 0);
1365     EXPECT_EQ(CheckTraceCommandOutput("hiperf dump -i /data/local/tmp/perf.data",
1366         {"magic:"}), true);
1367 }
1368 
1369 /**
1370  * @tc.name: ExcludeThreadName
1371  * @tc.desc: Test --exclude-thread option sucess
1372  * @tc.type: FUNC
1373  */
1374 HWTEST_F(SubCommandRecordTest, ExcludeThreadName, TestSize.Level1)
1375 {
__anon21b1720a0402(const PerfEventRecord& record) 1376     SubCommandRecord::CheckRecordCallBack callback = [](const PerfEventRecord& record) {
1377         if (record.GetType() == PERF_RECORD_SAMPLE) {
1378             const PerfRecordSample& recordSample = static_cast<const PerfRecordSample&>(record);
1379             std::string threadName = ReadFileToString(StringPrintf("/proc/%d/comm", recordSample.data_.tid));
1380             if (threadName == "DfxWatchdog") {
1381                 _exit(1);
1382             }
1383         }
1384     };
1385     ForkAndRunTest("-d 2 --exclude-thread DfxWatchdog ", true, true, callback);
1386 }
1387 
1388 /**
1389  * @tc.name: ExcludeThreadNames
1390  * @tc.desc: Test --exclude-thread option multi threads
1391  * @tc.type: FUNC
1392  */
1393 HWTEST_F(SubCommandRecordTest, ExcludeThreadNames, TestSize.Level1)
1394 {
__anon21b1720a0502(const PerfEventRecord& record) 1395     SubCommandRecord::CheckRecordCallBack callback = [](const PerfEventRecord& record) {
1396         if (record.GetType() == PERF_RECORD_SAMPLE) {
1397             const PerfRecordSample& recordSample = static_cast<const PerfRecordSample&>(record);
1398             std::string threadName = ReadFileToString(StringPrintf("/proc/%d/comm", recordSample.data_.tid));
1399             if (threadName == "DfxWatchdog" || threadName == "GC_WorkerThread") {
1400                 _exit(1);
1401             }
1402         }
1403     };
1404     ForkAndRunTest("-d 2 --exclude-thread DfxWatchdog,GC_WorkerThread ", true, true, callback);
1405 }
1406 
1407 /**
1408  * @tc.name: ExcludeErrorThreadName
1409  * @tc.desc: Test --exclude-thread option error thread name
1410  * @tc.type: FUNC
1411  */
1412 HWTEST_F(SubCommandRecordTest, ExcludeErrorThreadName, TestSize.Level1)
1413 {
__anon21b1720a0602(const PerfEventRecord& record) 1414     SubCommandRecord::CheckRecordCallBack callback = [](const PerfEventRecord& record) {
1415         if (record.GetType() == PERF_RECORD_SAMPLE) {
1416             const PerfRecordSample& recordSample = static_cast<const PerfRecordSample&>(record);
1417             std::string threadName = ReadFileToString(StringPrintf("/proc/%d/comm", recordSample.data_.tid));
1418             if (threadName == "test") {
1419                 _exit(1);
1420             }
1421         }
1422     };
1423     ForkAndRunTest("-d 2 --exclude-thread test ", true, true, callback);
1424 }
1425 
1426 /**
1427  * @tc.name: ExcludeErrorThreadNames
1428  * @tc.desc: Test --exclude-thread option multi error thread names
1429  * @tc.type: FUNC
1430  */
1431 HWTEST_F(SubCommandRecordTest, ExcludeErrorThreadNames, TestSize.Level1)
1432 {
__anon21b1720a0702(const PerfEventRecord& record) 1433     SubCommandRecord::CheckRecordCallBack callback = [](const PerfEventRecord& record) {
1434         if (record.GetType() == PERF_RECORD_SAMPLE) {
1435             const PerfRecordSample& recordSample = static_cast<const PerfRecordSample&>(record);
1436             std::string threadName = ReadFileToString(StringPrintf("/proc/%d/comm", recordSample.data_.tid));
1437             if (threadName == "test1" || threadName == "test2") {
1438                 _exit(1);
1439             }
1440         }
1441     };
1442     ForkAndRunTest("-d 2 --exclude-thread test1,test2 ", true, true, callback);
1443 }
1444 
1445 /**
1446  * @tc.name: ExcludeTids
1447  * @tc.desc: Test --exclude-tid
1448  * @tc.type: FUNC
1449  */
1450 HWTEST_F(SubCommandRecordTest, ExcludeTids, TestSize.Level1)
1451 {
__anon21b1720a0802(const PerfEventRecord& record) 1452     SubCommandRecord::CheckRecordCallBack callback = [](const PerfEventRecord& record) {
1453         if (record.GetType() == PERF_RECORD_SAMPLE) {
1454             const PerfRecordSample& recordSample = static_cast<const PerfRecordSample&>(record);
1455             if (recordSample.data_.tid == 200) {
1456                 _exit(1);
1457             }
1458         }
1459     };
1460     ForkAndRunTest("-d 2 -s dwarf -f 2000 --exclude-tid 200", true, true, callback);
1461 }
1462 
1463 /**
1464  * @tc.name: ExcludeThread
1465  * @tc.desc: Test --exclude-thread
1466  * @tc.type: FUNC
1467  */
1468 HWTEST_F(SubCommandRecordTest, ExcludeThread, TestSize.Level1)
1469 {
__anon21b1720a0902(const PerfEventRecord& record) 1470     SubCommandRecord::CheckRecordCallBack callback = [](const PerfEventRecord& record) {
1471         if (record.GetType() == PERF_RECORD_SAMPLE) {
1472             const PerfRecordSample& recordSample = static_cast<const PerfRecordSample&>(record);
1473             std::string threadName = ReadFileToString(StringPrintf("/proc/%d/comm", recordSample.data_.tid));
1474             if (threadName == "com.app.test") {
1475                 _exit(1);
1476             }
1477         }
1478     };
1479     ForkAndRunTest("-d 2 -s dwarf -f 2000 --exclude-thread com.app.test", true, true, callback);
1480 }
1481 
1482 /**
1483  * @tc.name: ExcludeMixedThreadName
1484  * @tc.desc: Test --exclude-thread option mixed correct name and error name
1485  * @tc.type: FUNC
1486  */
1487 HWTEST_F(SubCommandRecordTest, ExcludeMixedThreadName, TestSize.Level1)
1488 {
__anon21b1720a0a02(const PerfEventRecord& record) 1489     SubCommandRecord::CheckRecordCallBack callback = [](const PerfEventRecord& record) {
1490         if (record.GetType() == PERF_RECORD_SAMPLE) {
1491             const PerfRecordSample& recordSample = static_cast<const PerfRecordSample&>(record);
1492             std::string threadName = ReadFileToString(StringPrintf("/proc/%d/comm", recordSample.data_.tid));
1493             if (threadName == "DfxWatchdog" || threadName == "test") {
1494                 _exit(1);
1495             }
1496         }
1497     };
1498     ForkAndRunTest("-d 2 --exclude-thread DfxWatchdog,test ", true, true, callback);
1499 }
1500 
1501 // --restart
1502 HWTEST_F(SubCommandRecordTest, ReStartNotApp1, TestSize.Level3)
1503 {
1504     TestRecordCommand("-p 5 --restart ", false, false);
1505 }
1506 
1507 HWTEST_F(SubCommandRecordTest, ReStartNotApp2, TestSize.Level3)
1508 {
1509     TestRecordCommand("-a --restart ", false, false);
1510 }
1511 
1512 HWTEST_F(SubCommandRecordTest, ReStartNotApp3, TestSize.Level3)
1513 {
1514     TestRecordCommand("-p 5 -a --restart ", false, false);
1515 }
1516 
1517 HWTEST_F(SubCommandRecordTest, ReStartConflict, TestSize.Level3)
1518 {
1519     TestRecordCommand("--restart -a ", false, true);
1520 }
1521 
1522 HWTEST_F(SubCommandRecordTest, ReStart, TestSize.Level0)
1523 {
1524     TestRecordCommand("--restart ", false, true);
1525 }
1526 
1527 /**
1528  * @tc.name: CmdLinesSizeSucess
1529  * @tc.desc: Test --cmdline-size option
1530  * @tc.type: FUNC
1531  */
1532 HWTEST_F(SubCommandRecordTest, CmdLinesSizeSucess, TestSize.Level1)
1533 {
1534     ForkAndRunTest("-d 2 --cmdline-size 1024 ", true);
1535 }
1536 
1537 /**
1538  * @tc.name: CmdLinesSizeOutRange
1539  * @tc.desc: Test --cmdline-size option
1540  * @tc.type: FUNC
1541  */
1542 HWTEST_F(SubCommandRecordTest, CmdLinesSizeOutRange, TestSize.Level3)
1543 {
1544     TestRecordCommand("-d 2 --cmdline-size 8192 ", false);
1545 }
1546 
1547 /**
1548  * @tc.name: CmdLinesSizeNotPowerOf2
1549  * @tc.desc: Test --cmdline-size option
1550  * @tc.type: FUNC
1551  */
1552 HWTEST_F(SubCommandRecordTest, CmdLinesSizeNotPowerOf2, TestSize.Level3)
1553 {
1554     TestRecordCommand("-d 2 --cmdline-size 1000 ", false);
1555 }
1556 
1557 /**
1558  * @tc.name: EnableDebugInfoSymbolicFp
1559  * @tc.desc: Test --enable-debuginfo-symbolic option with -s fp
1560  * @tc.type: FUNC
1561  */
1562 HWTEST_F(SubCommandRecordTest, EnableDebugInfoSymbolicFp, TestSize.Level1)
1563 {
1564     ForkAndRunTest("-d 2 -s fp --enable-debuginfo-symbolic ", true);
1565 }
1566 
1567 /**
1568  * @tc.name: EnableDebugInfoSymbolicDwarf
1569  * @tc.desc: Test --enable-debuginfo-symbolic option with -s dwarf
1570  * @tc.type: FUNC
1571  */
1572 HWTEST_F(SubCommandRecordTest, EnableDebugInfoSymbolicDwarf, TestSize.Level1)
1573 {
1574     ForkAndRunTest("-d 2 -s dwarf --enable-debuginfo-symbolic ", true);
1575 }
1576 
1577 /**
1578  * @tc.name: CallChainUserOnlyFp
1579  * @tc.desc: Test --callchain-useronly option with fp
1580  * @tc.type: FUNC
1581  */
1582 HWTEST_F(SubCommandRecordTest, CallChainUserOnlyFp, TestSize.Level3)
1583 {
1584     ForkAndRunTest("-d 2 -s fp --callchain-useronly", true, true);
1585 }
1586 
1587 /**
1588  * @tc.name: CallChainUserOnlyDwarf
1589  * @tc.desc: Test --callchain-useronly option with dwarf
1590  * @tc.type: FUNC
1591  */
1592 HWTEST_F(SubCommandRecordTest, CallChainUserOnlyDwarf, TestSize.Level1)
1593 {
1594     ForkAndRunTest("-d 2 -s dwarf --callchain-useronly", true, true);
1595 }
1596 
1597 /**
1598  * @tc.name: CallChainUserOnlyError
1599  * @tc.desc: Test --callchain-useronly option without fp/dwarf
1600  * @tc.type: FUNC
1601  */
1602 HWTEST_F(SubCommandRecordTest, CallChainUserOnly, TestSize.Level3)
1603 {
1604     ForkAndRunTest("-d 2 --callchain-useronly", true, true);
1605 }
1606 
1607 /**
1608  * @tc.name: DedupStack
1609  * @tc.desc: Test --dedup_stack option
1610  * @tc.type: FUNC
1611  */
1612 HWTEST_F(SubCommandRecordTest, DedupStack, TestSize.Level1)
1613 {
1614     ForkAndRunTest("-d 2 -s dwarf --dedup_stack", true, true);
1615 }
1616 
1617 /**
1618  * @tc.name: DedupStackErr
1619  * @tc.desc: Test --dedup_stack option with -a
1620  * @tc.type: FUNC
1621  */
1622 HWTEST_F(SubCommandRecordTest, DedupStackErr, TestSize.Level3)
1623 {
1624     TestRecordCommand("-d 2 -a -s dwarf --dedup_stack", false, false);
1625 }
1626 
1627 /**
1628  * @tc.name: TestNoFork
1629  * @tc.desc: Test no fork
1630  * @tc.type: FUNC
1631  */
1632 HWTEST_F(SubCommandRecordTest, TestNoFork, TestSize.Level1)
1633 {
1634     TestRecordCommand("-d 2 -s dwarf --dedup_stack -f 2000 --cmdline-size 1024", true, true);
1635 }
1636 
1637 /**
1638  * @tc.name: TestAllNoFork
1639  * @tc.desc: Test no fork with -a
1640  * @tc.type: FUNC
1641  */
1642 HWTEST_F(SubCommandRecordTest, TestAllNoFork, TestSize.Level1)
1643 {
1644     TestRecordCommand("-d 2 -a -s dwarf --clockid monotonic --exclude-hiperf", true, false);
1645 }
1646 
1647 /**
1648  * @tc.name: CreateFifoServer
1649  * @tc.desc: Test create Fipo server
1650  * @tc.type: FUNC
1651  */
1652 HWTEST_F(SubCommandRecordTest, CreateFifoServer, TestSize.Level1)
1653 {
1654     SubCommandRecord cmd;
1655     EXPECT_EQ(cmd.CreateFifoServer(), false);
1656 }
1657 
1658 /**
1659  * @tc.name: SendFifoAndWaitReply
1660  * @tc.desc: Test send Fifo and wait reply
1661  * @tc.type: FUNC
1662  */
1663 HWTEST_F(SubCommandRecordTest, SendFifoAndWaitReply, TestSize.Level1)
1664 {
1665     SubCommandRecord cmd;
1666     std::string test = "test";
1667     EXPECT_EQ(cmd.perfPipe_.SendFifoAndWaitReply(test, CONTROL_WAITREPY_TOMEOUT), false);
1668 }
1669 
1670 /**
1671  * @tc.name: ReportErr
1672  * @tc.desc: Test report option error
1673  * @tc.type: FUNC
1674  */
1675 HWTEST_F(SubCommandRecordTest, ReportErr, TestSize.Level3)
1676 {
1677     TestRecordCommand("-d 2 -a --report ", false, false);
1678 }
1679 
1680 /**
1681  * @tc.name: TestHasReport
1682  * @tc.desc: Test --report option
1683  * @tc.type: FUNC
1684  */
1685 HWTEST_F(SubCommandRecordTest, TestHasReport, TestSize.Level1)
1686 {
1687     TestRecordCommand("-d 2 -s dwarf --report", true, true);
1688 }
1689 
1690 /**
1691  * @tc.name: TraceCommand
1692  * @tc.desc: Test TraceCommand option
1693  * @tc.type: FUNC
1694  */
1695 HWTEST_F(SubCommandRecordTest, TraceCommand, TestSize.Level1)
1696 {
1697     TestRecordCommand("-d 2 -s dwarf ls", true, false);
1698 }
1699 
1700 /**
1701  * @tc.name: TraceCommandErr
1702  * @tc.desc: Test InvalidCommand option
1703  * @tc.type: FUNC
1704  */
1705 HWTEST_F(SubCommandRecordTest, TraceCommandErr, TestSize.Level3)
1706 {
1707     TestRecordCommand("-d 2 -s dwarf invalidcommand", false, false);
1708 }
1709 
1710 /**
1711  * @tc.name: TestInputErr
1712  * @tc.desc: Test input with -a
1713  * @tc.type: FUNC
1714  */
1715 HWTEST_F(SubCommandRecordTest, TestInputErr, TestSize.Level3)
1716 {
1717     TestRecordCommand("-d 2 -a -s dwarf -f 2000 --pipe_input", false, false);
1718 }
1719 
1720 /**
1721  * @tc.name: TestOutputErr
1722  * @tc.desc: Test output with -a
1723  * @tc.type: FUNC
1724  */
1725 HWTEST_F(SubCommandRecordTest, TestOutputErr, TestSize.Level3)
1726 {
1727     TestRecordCommand("-d 2 -a -s dwarf -f 2000 --pipe_output", false, false);
1728 }
1729 
1730 /**
1731  * @tc.name: TestBranchFilterErr
1732  * @tc.desc: Test branch filter with -a
1733  * @tc.type: FUNC
1734  */
1735 HWTEST_F(SubCommandRecordTest, TestBranchFilterErr, TestSize.Level3)
1736 {
1737     TestRecordCommand("-d 2 -a -s dwarf -f 2000 -j", false, false);
1738 }
1739 
1740 /**
1741  * @tc.name: TestCallStackErr
1742  * @tc.desc: Test call stack with -a
1743  * @tc.type: FUNC
1744  */
1745 HWTEST_F(SubCommandRecordTest, TestCallStackErr, TestSize.Level3)
1746 {
1747     TestRecordCommand("-d 2 -a -f 2000 --call-stack", false, false);
1748 }
1749 
1750 /**
1751  * @tc.name: TestEventGroupErr
1752  * @tc.desc: Test event group with -a
1753  * @tc.type: FUNC
1754  */
1755 HWTEST_F(SubCommandRecordTest, TestEventGroupErr, TestSize.Level3)
1756 {
1757     TestRecordCommand("-d 2 -a -f 2000 -g", false, false);
1758 }
1759 
1760 /**
1761  * @tc.name: TestExcludeThreadErr
1762  * @tc.desc: Test exclude-thread with -a
1763  * @tc.type: FUNC
1764  */
1765 HWTEST_F(SubCommandRecordTest, TestExcludeThreadErr, TestSize.Level3)
1766 {
1767     TestRecordCommand("-d 2 -a -f 2000 --exclude-thread", false, false);
1768 }
1769 
1770 /**
1771  * @tc.name: TestSymbolDirErr
1772  * @tc.desc: Test symbol-dir with -a
1773  * @tc.type: FUNC
1774  */
1775 HWTEST_F(SubCommandRecordTest, TestSymbolDirErr, TestSize.Level3)
1776 {
1777     TestRecordCommand("-d 2 -a -f 2000 --symbol-dir", false, false);
1778 }
1779 
1780 /**
1781  * @tc.name: TestControlErr
1782  * @tc.desc: Test control with -a
1783  * @tc.type: FUNC
1784  */
1785 HWTEST_F(SubCommandRecordTest, TestControlErr, TestSize.Level3)
1786 {
1787     TestRecordCommand("-d 2 -a -f 2000 --control", false, false);
1788 }
1789 
1790 /**
1791  * @tc.name: TestCmdlineSizeErr
1792  * @tc.desc: Test cmdline-size with -a
1793  * @tc.type: FUNC
1794  */
1795 HWTEST_F(SubCommandRecordTest, TestCmdlineSizeErr, TestSize.Level3)
1796 {
1797     TestRecordCommand("-d 2 -a -f 2000 --cmdline-size", false, false);
1798 }
1799 
1800 /**
1801  * @tc.name: AddReportArgs
1802  * @tc.desc: Test AddReportArgs with -a
1803  * @tc.type: FUNC
1804  */
1805 HWTEST_F(SubCommandRecordTest, ReportSampleAll, TestSize.Level1)
1806 {
1807     SubCommandRecord command;
1808     command.targetSystemWide_ = true;
1809 
1810     CommandReporter reporter("record");
1811     reporter.isReported_ = true;
1812     command.AddReportArgs(reporter);
1813     EXPECT_EQ(reporter.targetProcess_, "ALL");
1814 }
1815 
1816 /**
1817  * @tc.name: AddReportArgs
1818  * @tc.desc: Test AddReportArgs with -p
1819  * @tc.type: FUNC
1820  */
1821 HWTEST_F(SubCommandRecordTest, ReportSamplePid, TestSize.Level1)
1822 {
1823     SubCommandRecord command;
1824     command.selectPids_ = { getpid() };
1825     std::string name = GetProcessName(getpid());
1826 
1827     CommandReporter reporter("record");
1828     reporter.isReported_ = true;
1829     command.AddReportArgs(reporter);
1830     EXPECT_EQ(reporter.targetProcess_, name);
1831 }
1832 
1833 /**
1834  * @tc.name: AddReportArgs
1835  * @tc.desc: Test AddReportArgs with --app
1836  * @tc.type: FUNC
1837  */
1838 HWTEST_F(SubCommandRecordTest, ReportSampleApp, TestSize.Level1)
1839 {
1840     SubCommandRecord command;
1841     command.appPackage_ = "com.test.app";
1842 
1843     CommandReporter reporter("record");
1844     reporter.isReported_ = true;
1845     command.AddReportArgs(reporter);
1846     EXPECT_EQ(reporter.targetProcess_, "com.test.app");
1847 }
1848 
1849 /**
1850  * @tc.name: ChecKernel
1851  * @tc.desc: Test kernel version
1852  * @tc.type: FUNC
1853  */
1854 HWTEST_F(SubCommandRecordTest, ChecKernel, TestSize.Level1)
1855 {
1856     utsname unameBuf;
1857     if ((uname(&unameBuf)) == 0) {
1858         std::string osrelease = unameBuf.release;
1859         std::string sysname = unameBuf.sysname;
1860         EXPECT_EQ(osrelease.find(HMKERNEL) != std::string::npos || sysname.find("Linux") != std::string::npos, true);
1861     }
1862 }
1863 
1864 /**
1865  * @tc.name: RecordAndReport
1866  * @tc.desc: Test record and report
1867  * @tc.type: FUNC
1868  */
1869 HWTEST_F(SubCommandRecordTest, RecordAndReport, TestSize.Level1)
1870 {
1871     const std::string cmd = "hiperf record -d 1 -s dwarf -f 100 --app " +
1872                             SubCommandRecordTest::testProcesses +
1873                             " -o /data/local/tmp/perf.data";
1874     EXPECT_EQ(CheckTraceCommandOutput(cmd, {"Process and Saving data..."}), true);
1875     EXPECT_EQ(CheckTraceCommandOutput(
1876         "hiperf report --json -i /data/local/tmp/perf.data -o /data/local/tmp/perf.json",
1877         {"report done"}),
1878               true);
1879     EXPECT_TRUE(CheckJsonReport("/data/local/tmp/perf.json", ""));
1880 }
1881 
1882 /**
1883  * @tc.name: GetInstance
1884  * @tc.desc: Test GetInstance
1885  * @tc.type: FUNC
1886  */
1887 HWTEST_F(SubCommandRecordTest, GetInstance, TestSize.Level1)
1888 {
1889     StdoutRecord stdoutRecord;
1890     stdoutRecord.Start();
1891 
1892     EXPECT_EQ(SubCommandRecord::GetInstance().Name(), "record");
1893 }
1894 
1895 /**
1896  * @tc.name: CheckExcludeArgs
1897  * @tc.desc: Test CheckExcludeArgs
1898  * @tc.type: FUNC
1899  */
1900 HWTEST_F(SubCommandRecordTest, CheckExcludeArgs, TestSize.Level1)
1901 {
1902     StdoutRecord stdoutRecord;
1903     stdoutRecord.Start();
1904 
1905     SubCommandRecord record;
1906     record.targetSystemWide_ = true;
1907     record.excludeTidArgs_ = { 1, 2, 3 };
1908     EXPECT_EQ(record.CheckExcludeArgs(), false);
1909 
1910     record.excludeTidArgs_ = {};
1911     record.excludeThreadNameArgs_ = { "a" };
1912     EXPECT_EQ(record.CheckExcludeArgs(), false);
1913 
1914     record.targetSystemWide_ = false;
1915     record.excludeProcessNameArgs_ = { "a" };
1916     EXPECT_EQ(record.CheckExcludeArgs(), false);
1917 
1918     record.excludeProcessNameArgs_ = {};
1919     record.excludeHiperf_ = true;
1920     EXPECT_EQ(record.CheckExcludeArgs(), false);
1921 
1922     record.excludeHiperf_ = false;
1923     EXPECT_EQ(record.CheckExcludeArgs(), true);
1924 }
1925 
1926 /**
1927  * @tc.name: ParseControlCmd
1928  * @tc.desc: Test ParseControlCmd
1929  * @tc.type: FUNC
1930  */
1931 HWTEST_F(SubCommandRecordTest, ParseControlCmd, TestSize.Level1)
1932 {
1933     StdoutRecord stdoutRecord;
1934     stdoutRecord.Start();
1935 
1936     SubCommandRecord record;
1937     std::vector<std::string> strs {"prepare", "start", "pause", "resume", "output", "stop", ""};
1938     for (const auto& str : strs) {
1939         EXPECT_TRUE(record.ParseControlCmd(str));
1940     }
1941 
1942     EXPECT_FALSE(record.ParseControlCmd("ABC"));
1943 }
1944 
1945 /**
1946  * @tc.name: PostOutputRecordFile
1947  * @tc.desc: Test PostOutputRecordFile
1948  * @tc.type: FUNC
1949  */
1950 HWTEST_F(SubCommandRecordTest, PostOutputRecordFile, TestSize.Level1)
1951 {
1952     StdoutRecord stdoutRecord;
1953     stdoutRecord.Start();
1954 
1955     SubCommandRecord record;
1956     record.fileWriter_ = std::make_unique<PerfFileWriter>();
1957     record.outputEnd_ = false;
1958     EXPECT_EQ(record.PostOutputRecordFile(false), true);
1959     EXPECT_EQ(record.fileWriter_, nullptr);
1960     EXPECT_EQ(record.outputEnd_, true);
1961 }
1962 
1963 /**
1964  * @tc.name: InitControlCommandHandlerMap
1965  * @tc.desc: Test InitControlCommandHandlerMap
1966  * @tc.type: FUNC
1967  */
1968 HWTEST_F(SubCommandRecordTest, InitControlCommandHandlerMap, TestSize.Level1)
1969 {
1970     StdoutRecord stdoutRecord;
1971     stdoutRecord.Start();
1972 
1973     SubCommandRecord record;
1974     record.InitControlCommandHandlerMap();
1975     EXPECT_EQ(record.controlCommandHandlerMap_.size(), 7u);
1976 }
1977 
1978 /**
1979  * @tc.name: CollectExcludeThread
1980  * @tc.desc: Test CollectExcludeThread
1981  * @tc.type: FUNC
1982  */
1983 HWTEST_F(SubCommandRecordTest, CollectExcludeThread1, TestSize.Level1)
1984 {
1985     StdoutRecord stdoutRecord;
1986     stdoutRecord.Start();
1987 
1988     SubCommandRecord record;
1989     record.excludeHiperf_ = false;
1990     record.excludeTids_ = {};
1991     pid_t pid = getpid();
1992     std::string name = GetProcessName(pid);
1993     size_t pos = name.find_last_of("/");
1994     if (pos != std::string::npos) {
1995         name = name.substr(pos + 1);
1996     }
1997     record.excludeProcessNameArgs_ = { name };
1998     record.excludeTidArgs_ = {};
1999     record.CollectExcludeThread();
2000 
2001     ASSERT_GE(record.excludePids_.size(), 1u);
2002     EXPECT_EQ(record.excludeTids_.size(), 0u);
2003     bool get = false;
2004     for (pid_t id : record.excludePids_) {
2005         if (pid == id) {
2006             get = true;
2007             break;
2008         }
2009     }
2010     EXPECT_EQ(get, true);
2011 }
2012 
2013 /**
2014  * @tc.name: SetExcludeHiperf
2015  * @tc.desc: Test SetExcludeHiperf
2016  * @tc.type: FUNC
2017  */
2018 HWTEST_F(SubCommandRecordTest, SetExcludeHiperf, TestSize.Level1)
2019 {
2020     StdoutRecord stdoutRecord;
2021     stdoutRecord.Start();
2022 
2023     SubCommandRecord record;
2024     record.excludeHiperf_ = true;
2025     pid_t pid = getpid();
2026     record.SetExcludeHiperf();
2027 
2028     ASSERT_EQ(record.excludePids_.size(), 1u);
2029     EXPECT_EQ(*(record.excludePids_.begin()), pid);
2030 }
2031 
2032 /**
2033  * @tc.name: CollectExcludeThread
2034  * @tc.desc: Test CollectExcludeThread
2035  * @tc.type: FUNC
2036  */
2037 HWTEST_F(SubCommandRecordTest, CollectExcludeThread3, TestSize.Level1)
2038 {
2039     StdoutRecord stdoutRecord;
2040     stdoutRecord.Start();
2041 
2042     SubCommandRecord record;
2043     record.excludeHiperf_ = false;
2044     record.excludeTids_ = {};
2045     record.excludeProcessNameArgs_ = {};
2046     record.excludeTidArgs_ = {1, 2, 3};
2047     record.CollectExcludeThread();
2048 
2049     ASSERT_EQ(record.excludePids_.size(), 0u);
2050     ASSERT_EQ(record.excludeTids_.size(), 3u);
2051 
2052     for (const auto& tid : record.excludeTidArgs_) {
2053         EXPECT_TRUE(record.excludeTids_.find(tid) != record.excludeTids_.end());
2054     }
2055 }
2056 
2057 /**
2058  * @tc.name: IsThreadExcluded
2059  * @tc.desc: Test IsThreadExcluded
2060  * @tc.type: FUNC
2061  */
2062 HWTEST_F(SubCommandRecordTest, IsThreadExcluded, TestSize.Level1)
2063 {
2064     StdoutRecord stdoutRecord;
2065     stdoutRecord.Start();
2066 
2067     SubCommandRecord record;
2068     record.excludePids_ = { 1, 2 };
2069     record.excludeTids_ = { 1, 2, 3 };
2070 
2071     EXPECT_EQ(record.IsThreadExcluded(1, 1), true);
2072     EXPECT_EQ(record.IsThreadExcluded(1, 3), true);
2073     EXPECT_EQ(record.IsThreadExcluded(1, 4), true);
2074     EXPECT_EQ(record.IsThreadExcluded(3, 1), true);
2075     EXPECT_EQ(record.IsThreadExcluded(3, 5), false);
2076 }
2077 
2078 /**
2079  * @tc.name: CheckBacktrackOption
2080  * @tc.desc: Test CheckBacktrackOption
2081  * @tc.type: FUNC
2082  */
2083 HWTEST_F(SubCommandRecordTest, CheckBacktrackOption, TestSize.Level1)
2084 {
2085     StdoutRecord stdoutRecord;
2086     stdoutRecord.Start();
2087 
2088     SubCommandRecord record;
2089     record.backtrack_ = false;
2090     EXPECT_EQ(record.CheckBacktrackOption(), true);
2091 
2092     record.backtrack_ = true;
2093     record.controlCmd_ = {};
2094     record.clientPipeInput_ = -1;
2095     EXPECT_EQ(record.CheckBacktrackOption(), false);
2096 
2097     record.clientPipeInput_ = 0;
2098     record.clockId_ = "";
2099     EXPECT_EQ(record.CheckBacktrackOption(), true);
2100 
2101     record.clockId_ = "realtime";
2102     EXPECT_EQ(record.CheckBacktrackOption(), false);
2103 
2104     record.clockId_ = "boottime";
2105     EXPECT_EQ(record.CheckBacktrackOption(), true);
2106 }
2107 
2108 /**
2109  * @tc.name: GetSpeOptions
2110  * @tc.desc: Test GetSpeOptions
2111  * @tc.type: FUNC
2112  */
2113 HWTEST_F(SubCommandRecordTest, GetSpeOptions, TestSize.Level1)
2114 {
2115     constexpr uint64_t disable     = 0;
2116     constexpr uint64_t enable      = 1;
2117     constexpr uint64_t minLatency  = 10;
2118     constexpr uint64_t eventFilter = 0x8;
2119     SubCommandRecord command;
2120     command.selectEvents_ = {"arm_spe_0/load_filter=1", "branch_filter=1", "pct_enable=1",
2121                              "store_filter=0", "ts_enable=1", "pa_enable=0", "jitter=1",
2122                              "min_latency=10", "event_filter=0x8/"};
2123     EXPECT_EQ(command.GetSpeOptions(), true);
2124     EXPECT_EQ(command.speOptMap_["ts_enable"], enable);
2125     EXPECT_EQ(command.speOptMap_["pa_enable"], disable);
2126     EXPECT_EQ(command.speOptMap_["pct_enable"], enable);
2127     EXPECT_EQ(command.speOptMap_["branch_filter"], enable);
2128     EXPECT_EQ(command.speOptMap_["load_filter"], enable);
2129     EXPECT_EQ(command.speOptMap_["store_filter"], disable);
2130     EXPECT_EQ(command.speOptMap_["jitter"], enable);
2131     EXPECT_EQ(command.speOptMap_["min_latency"], minLatency);
2132     EXPECT_EQ(command.speOptMap_["event_filter"], eventFilter);
2133 }
2134 
2135 /**
2136  * @tc.name: CheckSpeOption
2137  * @tc.desc: Test CheckSpeOption
2138  * @tc.type: FUNC
2139  */
2140 HWTEST_F(SubCommandRecordTest, CheckSpeOption, TestSize.Level1)
2141 {
2142     constexpr uint64_t disable = 0;
2143     constexpr uint64_t enable  = 1;
2144     SubCommandRecord command;
2145     command.speOptMap_["ts_enable"] = enable; // 2 : invalid value
2146     command.speOptMap_["pa_enable"] = enable;
2147     command.speOptMap_["pct_enable"] = enable;
2148     command.speOptMap_["branch_filter"] = enable;
2149     command.speOptMap_["load_filter"] = disable;
2150     command.speOptMap_["store_filter"] = enable;
2151     command.speOptMap_["jitter"] = enable;
2152     EXPECT_EQ(command.CheckSpeOption(), true);
2153 }
2154 
2155 /**
2156  * @tc.name: CheckSpeOptionErr
2157  * @tc.desc: Test CheckSpeOption
2158  * @tc.type: FUNC
2159  */
2160 HWTEST_F(SubCommandRecordTest, CheckSpeOptionErr, TestSize.Level3)
2161 {
2162     constexpr uint64_t disable = 0;
2163     constexpr uint64_t enable  = 1;
2164     constexpr uint64_t invalid = 20;
2165     SubCommandRecord command;
2166     command.speOptMap_["branch_filter"] = invalid;
2167     command.speOptMap_["load_filter"] = disable;
2168     command.speOptMap_["jitter"] = enable;
2169     EXPECT_EQ(command.CheckSpeOption(), false);
2170 }
2171 
2172 HWTEST_F(SubCommandRecordTest, CheckThreadName, TestSize.Level1)
2173 {
2174     bool checkRet = false;
2175     SubCommandRecord cmd;
2176     PerfEvents event;
2177     pid_t timeTid = 0;
2178     event.backtrack_ = true;
2179     event.eventGroupItem_.emplace_back();
2180     event.eventGroupItem_[0].eventItems.emplace_back();
2181     event.readRecordThreadRunning_ = true;
2182 
__anon21b1720a0b02(PerfEventRecord& record) 2183     auto saveRecord = [](PerfEventRecord& record) -> bool {
2184         return true;
2185     };
2186     cmd.virtualRuntime_.SetRecordMode(saveRecord);
2187     EXPECT_EQ(event.PrepareRecordThread(), true);
2188     std::this_thread::sleep_for(1s);
2189     std::vector<pid_t> tids = GetSubthreadIDs(getpid());
2190     EXPECT_FALSE(tids.empty());
2191     bool get = false;
2192     for (const pid_t tid : tids) {
2193         std::string threadName = ReadFileToString(StringPrintf("/proc/%d/comm", tid));
2194         while (threadName.back() == '\0' || threadName.back() == '\n') {
2195             threadName.pop_back();
2196         }
2197         if (threadName == "timer_thread") {
2198             timeTid = tid;
2199             get = true;
2200             break;
2201         }
2202     }
2203     EXPECT_EQ(get, true);
2204 
2205     std::string recordCommand = "-t " + std::to_string(timeTid) + " -d 5 -s dwarf -o /data/local/tmp/tid_name.data";
2206     TestRecordCommand(recordCommand, true, false);
2207     StdoutRecord stdoutRecord;
2208     stdoutRecord.Start();
2209     EXPECT_EQ(Command::DispatchCommand("report -i /data/local/tmp/tid_name.data -o /data/local/tmp/tid_name.report"),
2210               true);
2211     std::string stringOut = stdoutRecord.Stop();
2212     EXPECT_EQ(stringOut.find("report done") != std::string::npos, true);
2213 
2214     std::ifstream ifs("/data/local/tmp/tid_name.report", std::ifstream::in);
2215     EXPECT_EQ(ifs.is_open(), true);
2216     std::string line;
2217     while (getline(ifs, line)) {
2218         if (line.find("timer_thread") != std::string::npos) {
2219             checkRet = true;
2220             break;
2221         }
2222     }
2223     ifs.close();
2224     EXPECT_EQ(checkRet, true);
2225 }
2226 
2227 HWTEST_F(SubCommandRecordTest, CheckDevhostMapOffset, TestSize.Level1)
2228 {
2229     if (IsHM()) {
2230         bool checkRet = false;
2231         SubCommandRecord cmd;
2232         cmd.SetHM();
2233         VirtualThread &kthread = cmd.virtualRuntime_.GetThread(cmd.virtualRuntime_.devhostPid_,
2234                                                             cmd.virtualRuntime_.devhostPid_);
2235         kthread.ParseDevhostMap(cmd.virtualRuntime_.devhostPid_);
2236         TestRecordCommand("-d 5 -s dwarf -o /data/local/tmp/test_maps.data", true, true);
2237         StdoutRecord stdoutRecord;
2238         stdoutRecord.Start();
2239         EXPECT_EQ(Command::DispatchCommand("dump -i /data/local/tmp/test_maps.data"), true);
2240         std::string stringOut = stdoutRecord.Stop();
2241         std::istringstream stream(stringOut);
2242 
2243         std::string line;
2244         bool isMmapRecord = false;
2245         bool isMmapFirstLine = false;
2246         uint64_t mapOffset = 0;
2247         while (getline(stream, line)) {
2248             if (strstr(line.c_str(), "record mmap:") != nullptr) {
2249                 isMmapRecord = true;
2250                 continue;
2251             }
2252             if (strstr(line.c_str(), "record sample:") != nullptr) {
2253                 break;
2254             }
2255             if (isMmapFirstLine) {
2256                 isMmapFirstLine = false;
2257                 uint64_t pgoff = 0;
2258                 int ret = sscanf_s(line.c_str(), "  %*s 0x%" PRIx64 ", %*s %*s", &pgoff);
2259                 constexpr int numSlices {1};
2260                 if (ret != numSlices) {
2261                     printf("unknown line %d: '%s' \n", ret, line.c_str());
2262                     continue;
2263                 }
2264                 EXPECT_EQ(mapOffset, pgoff);
2265                 checkRet = true;
2266                 continue;
2267             }
2268 
2269             if (isMmapRecord) {
2270                 isMmapRecord = false;
2271                 isMmapFirstLine = GetMemMapOffset(cmd.virtualRuntime_.devhostPid_, mapOffset, kthread.memMaps_, line);
2272             }
2273         }
2274         EXPECT_EQ(checkRet, true);
2275     }
2276 }
2277 
2278 HWTEST_F(SubCommandRecordTest, CheckGetCountFromFile, TestSize.Level1)
2279 {
2280     SubCommandRecord cmd;
2281     uint32_t cpuPresent = cmd.GetCountFromFile("/sys/devices/system/cpu/present");
2282     ASSERT_GT(cpuPresent, 1);
2283     uint32_t cpuOnline = cmd.GetCountFromFile("/sys/devices/system/cpu/online");
2284     ASSERT_GT(cpuOnline, 1);
2285 }
2286 
2287 HWTEST_F(SubCommandRecordTest, CheckProductCfg, TestSize.Level1)
2288 {
2289     SubCommandRecord cmd;
2290     cJSON* root = GetProductCfgRoot(cmd.PRODUCT_CONFIG_PATH);
2291     if (root) {
2292         size_t mmapPages = 0;
2293         EXPECT_EQ(GetCfgValue(cmd.PRODUCT_CONFIG_PATH, cmd.CFG_MAP_PAGES, mmapPages), true);
2294         cmd.GetMmapPagesCfg();
2295         cJSON_Delete(root);
2296     }
2297 }
2298 
2299 /**
2300  * @tc.name: TestOnSubCommand_control01
2301  * @tc.desc: prepare, start, stop
2302  * @tc.type: FUNC
2303  */
2304 HWTEST_F(SubCommandRecordTest, TestOnSubCommand_control01, TestSize.Level1)
2305 {
2306     ASSERT_TRUE(RunCmd("hiperf record --control stop"));
2307     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control prepare -a -o /data/local/tmp/perf_control01.data",
2308                                       {"create control hiperf sampling success"}),
2309               true);
2310     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control start", {"start sampling success"}),
2311               true);
2312     std::this_thread::sleep_for(std::chrono::seconds(1));
2313     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control stop", {"stop sampling success"}),
2314               true);
2315     EXPECT_EQ(CheckTraceCommandOutput(
2316         "hiperf report --json -i /data/local/tmp/perf_control01.data -o /data/local/tmp/perf.json",
2317         {"report done"}),
2318               true);
2319     EXPECT_TRUE(CheckJsonReport("/data/local/tmp/perf.json", "/system/bin/hiperf", 1));
2320 }
2321 
2322 /**
2323  * @tc.name: TestOnSubCommand_control_app
2324  * @tc.desc: prepare, start, stop with app
2325  * @tc.type: FUNC
2326  */
2327 HWTEST_F(SubCommandRecordTest, TestOnSubCommand_control_app, TestSize.Level1)
2328 {
2329     ASSERT_TRUE(RunCmd("hiperf record --control stop"));
2330     const std::string cmd = "hiperf record --control prepare --app " +
2331                             SubCommandRecordTest::testProcesses +
2332                             " -o /data/local/tmp/perf_control_app.data";
2333     EXPECT_EQ(CheckTraceCommandOutput(cmd, {"create control hiperf sampling success"}),
2334               true);
2335     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control start", {"start sampling success"}),
2336               true);
2337     std::this_thread::sleep_for(std::chrono::seconds(1));
2338     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control stop", {"stop sampling success"}),
2339               true);
2340     EXPECT_EQ(CheckTraceCommandOutput(
2341         "hiperf report --json -i /data/local/tmp/perf_control_app.data -o /data/local/tmp/perf.json",
2342         {"report done"}),
2343               true);
2344     EXPECT_TRUE(CheckJsonReport("/data/local/tmp/perf.json", ""));
2345 }
2346 
2347 /**
2348  * @tc.name: TestOnSubCommand_control02
2349  * @tc.desc: prepare, prepare
2350  * @tc.type: FUNC
2351  */
2352 HWTEST_F(SubCommandRecordTest, TestOnSubCommand_control02, TestSize.Level1)
2353 {
2354     ASSERT_TRUE(RunCmd("hiperf record --control stop"));
2355     ASSERT_TRUE(RunCmd("hiperf record --control prepare -a"));
2356     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control prepare -a",
2357                                       {"another sampling service is running"}),
2358               true);
2359 }
2360 
2361 /**
2362  * @tc.name: TestOnSubCommand_control03
2363  * @tc.desc: start, stop
2364  * @tc.type: FUNC
2365  */
2366 HWTEST_F(SubCommandRecordTest, TestOnSubCommand_control03, TestSize.Level1)
2367 {
2368     ASSERT_TRUE(RunCmd("hiperf record --control stop"));
2369     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control start", {"start sampling failed"}),
2370               true);
2371     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control stop", {"stop sampling failed"}),
2372               true);
2373 }
2374 
2375 /**
2376  * @tc.name: TestOnSubCommand_control04
2377  * @tc.desc: prepare, start, resume, pause, stop
2378  * @tc.type: FUNC
2379  */
2380 HWTEST_F(SubCommandRecordTest, TestOnSubCommand_control04, TestSize.Level1)
2381 {
2382     ASSERT_TRUE(RunCmd("hiperf record --control stop"));
2383     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control prepare -a",
2384                                       {"create control hiperf sampling success"}),
2385               true);
2386     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control start", {"start sampling success"}),
2387               true);
2388     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control resume", {"resume sampling success"}),
2389               true);
2390     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control pause", {"pause sampling success"}),
2391               true);
2392     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control stop", {"stop sampling success"}),
2393               true);
2394 }
2395 
2396 /**
2397  * @tc.name: TestOnSubCommand_control05
2398  * @tc.desc: prepare, start, output, stop
2399  * @tc.type: FUNC
2400  */
2401 HWTEST_F(SubCommandRecordTest, TestOnSubCommand_control05, TestSize.Level1)
2402 {
2403     ASSERT_TRUE(RunCmd("hiperf record --control stop"));
2404     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control prepare -a --backtrack",
2405                                       {"create control hiperf sampling success"}),
2406               true);
2407     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control start", {"start sampling success"}),
2408               true);
2409     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control output", {"output sampling success"}),
2410               true);
2411     EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control stop", {"stop sampling success"}),
2412               true);
2413 }
2414 
2415 /**
2416  * @tc.name: Control_Stability
2417  * @tc.desc: --control prepare, start, stop
2418  * @tc.type: FUNC
2419  */
2420 HWTEST_F(SubCommandRecordTest, Control_Stability, TestSize.Level1)
2421 {
2422     ASSERT_TRUE(RunCmd("hiperf record --control stop"));
2423     for (int i = 0; i < 10; i++) {  // 10: Number of loop
2424         EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control prepare -a -e hw-cpu-cycles,hw-instructions",
2425             {"create control hiperf sampling success"}), true);
2426         EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control start",
2427             {"start sampling success"}), true);
2428         EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control stop",
2429             {"stop sampling success"}), true);
2430     }
2431 }
2432 
2433 /**
2434  * @tc.name: TestOnSubCommand_WrongStopSeconds
2435  * @tc.type: FUNC
2436  */
2437 HWTEST_F(SubCommandRecordTest, WrongStopSeconds, TestSize.Level2)
2438 {
2439     std::string opt = "-d 123abc  ";
2440     TestRecordCommand(opt, false);
2441 }
2442 
2443 /**
2444  * @tc.name: TestOnSubCommand_OutPutFileName
2445  * @tc.type: FUNC
2446  */
2447 HWTEST_F(SubCommandRecordTest, OutPutFileName, TestSize.Level2)
2448 {
2449     EXPECT_EQ(CheckTraceCommandOutput("hiperf record -d 3 -a -o /data/log/hiperflog/perf.data",
2450         {"Invalid output file path, permission denied"}), true);
2451 }
2452 
2453 /**
2454  * @tc.name: TestOnSubCommand_OutPutFileName
2455  * @tc.type: FUNC
2456  */
2457 HWTEST_F(SubCommandRecordTest, GetOffsetNum, TestSize.Level1)
2458 {
2459     SubCommandRecord cmd;
2460     uint32_t offset = cmd.GetOffsetNum();
2461     EXPECT_GT(offset, 0);
2462 }
2463 
2464 /**
2465  * @tc.name: TestOnSubCommand_OutPutFileName
2466  * @tc.type: FUNC
2467  */
2468 HWTEST_F(SubCommandRecordTest, UpdateDevHostMaps1, TestSize.Level1)
2469 {
2470     constexpr uint32_t pid = 70;
2471     constexpr uint32_t tid = 70;
2472     constexpr uint32_t addr = 111;
2473     constexpr uint64_t len = 1000;
2474     constexpr uint64_t pgoff = 0;
2475     PerfRecordMmap recordIn {true, pid, tid, addr,
2476                              len, pgoff, "testdatammap"};
2477     SubCommandRecord cmd;
2478     cmd.devhostPid_ = pid;
2479     cmd.offset_ = cmd.GetOffsetNum();
2480     cmd.UpdateDevHostMaps(recordIn);
2481     EXPECT_EQ(recordIn.data_.addr, cmd.offset_ + addr);
2482 }
2483 
2484 /**
2485  * @tc.name: TestOnSubCommand_OutPutFileName
2486  * @tc.type: FUNC
2487  */
2488 HWTEST_F(SubCommandRecordTest, UpdateDevHostMaps2, TestSize.Level1)
2489 {
2490     constexpr uint32_t devhostPid = 71;
2491     constexpr uint32_t pid = 70;
2492     constexpr uint32_t tid = 70;
2493     constexpr uint32_t addr = 111;
2494     constexpr uint64_t len = 1000;
2495     constexpr uint64_t pgoff = 0;
2496     PerfRecordMmap recordIn {true, pid, tid, addr,
2497                              len, pgoff, "testdatammap"};
2498     SubCommandRecord cmd;
2499     cmd.devhostPid_ = devhostPid;
2500     cmd.offset_ = cmd.GetOffsetNum();
2501     cmd.UpdateDevHostMaps(recordIn);
2502     EXPECT_EQ(recordIn.data_.addr, addr);
2503 }
2504 
2505 /**
2506  * @tc.name: TestOnSubCommand_OutPutFileName
2507  * @tc.type: FUNC
2508  */
2509 HWTEST_F(SubCommandRecordTest, UpdateDevHostMaps3, TestSize.Level1)
2510 {
2511     constexpr uint32_t pid = 70;
2512     constexpr uint32_t tid = 70;
2513     constexpr uint32_t addr = 111;
2514     constexpr uint64_t len = 1000;
2515     constexpr uint64_t pgoff = 0;
2516     constexpr uint64_t testNum = 1;
2517     PerfRecordMmap2 recordIn {true, pid, tid, addr, len, pgoff,
2518                               testNum, testNum, testNum, testNum, testNum, "testdatammap2"};
2519     SubCommandRecord cmd;
2520     cmd.devhostPid_ = pid;
2521     cmd.offset_ = cmd.GetOffsetNum();
2522     cmd.UpdateDevHostMaps(recordIn);
2523     EXPECT_EQ(recordIn.data_.addr, cmd.offset_ + addr);
2524 }
2525 
2526 /**
2527  * @tc.name: TestOnSubCommand_OutPutFileName
2528  * @tc.type: FUNC
2529  */
2530 HWTEST_F(SubCommandRecordTest, UpdateDevHostMaps4, TestSize.Level1)
2531 {
2532     constexpr uint32_t devhostPid = 71;
2533     constexpr uint32_t pid = 70;
2534     constexpr uint32_t tid = 70;
2535     constexpr uint32_t addr = 111;
2536     constexpr uint64_t len = 1000;
2537     constexpr uint64_t pgoff = 0;
2538     constexpr uint64_t testNum = 1;
2539     PerfRecordMmap2 recordIn {true, pid, tid, addr, len, pgoff,
2540                               testNum, testNum, testNum, testNum, testNum, "testdatammap2"};
2541     SubCommandRecord cmd;
2542     cmd.devhostPid_ = devhostPid;
2543     cmd.offset_ = cmd.GetOffsetNum();
2544     cmd.UpdateDevHostMaps(recordIn);
2545     EXPECT_EQ(recordIn.data_.addr, addr);
2546 }
2547 } // namespace HiPerf
2548 } // namespace Developtools
2549 } // namespace OHOS
2550