• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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_report_test.h"
17 
18 #include "subcommand.h"
19 #include "subcommand_report.h"
20 #include "subcommand_test.h"
21 
22 using namespace testing::ext;
23 using namespace std;
24 using namespace OHOS::HiviewDFX;
25 namespace OHOS {
26 namespace Developtools {
27 namespace HiPerf {
28 class SubCommandReportTest : public testing::Test {
29 public:
30     const int DEFAULT_RUN_TIMEOUT_MS = 10000;
31 #if is_ohos
32     const std::string RESOURCE_PATH = "/data/test/resource/testdata/";
33 #else
34     const std::string RESOURCE_PATH = "./resource/testdata/";
35 #endif
36     static void SetUpTestCase(void);
37     static void TearDownTestCase(void);
38     void SetUp();
39     void TearDown();
40 
41     bool FindExpectStr(const std::string &stringOut, const std::string &counterNames) const;
42     bool FindExpectStrList(const std::string &stringOut,
43                            const std::vector<std::string> &counterNames) const;
44     bool FileCompare(const std::string &stringOut, const std::string &targetFile) const;
45     const std::vector<std::string> expectStr_ = {
46         "Heating", "count", "comm", "pid", "tid", "dso", "func",
47     };
48 };
SetUpTestCase()49 void SubCommandReportTest::SetUpTestCase() {}
50 
TearDownTestCase()51 void SubCommandReportTest::TearDownTestCase() {
52 }
53 
SetUp()54 void SubCommandReportTest::SetUp()
55 {
56     ASSERT_EQ(SubCommand::GetSubCommands().size(), 0u);
57     ASSERT_EQ(SubCommandReport::RegisterSubCommandReport(), true);
58     SubCommand::RegisterSubCommand("TEST_CMD_1", std::make_unique<SubCommandTest>("TEST_CMD_1"));
59 }
60 
TearDown()61 void SubCommandReportTest::TearDown()
62 {
63     SubCommand::ClearSubCommands();
64     ASSERT_EQ(SubCommand::GetSubCommands().size(), 0u);
65     MemoryHold::Get().Clean();
66 }
67 
FindExpectStr(const std::string & stringOut,const std::string & counterNames) const68 bool SubCommandReportTest::FindExpectStr(const std::string &stringOut,
69                                          const std::string &counterNames) const
70 {
71     auto lines = StringSplit(stringOut, "\n");
72     for (auto line : lines) {
73         if (line.find(counterNames.c_str()) != std::string::npos) {
74             return true;
75         }
76     }
77     return false;
78 }
79 
FindExpectStrList(const std::string & stringOut,const std::vector<std::string> & counterNames) const80 bool SubCommandReportTest::FindExpectStrList(const std::string &stringOut,
81                                              const std::vector<std::string> &counterNames) const
82 {
83     for (auto name : counterNames) {
84         if (stringOut.find(name) != std::string::npos) {
85             return true;
86         }
87     }
88     return false;
89 }
90 
FileCompare(const std::string & stringOut,const std::string & targetFile) const91 bool SubCommandReportTest::FileCompare(const std::string &stringOut,
92                                        const std::string &targetFile) const
93 {
94     std::vector<std::string> actualLines = StringSplit(stringOut, "\n");
95     std::vector<std::string> expectLines = StringSplit(ReadFileToString(targetFile), "\n");
96 
97     for (int i = 0; i < (int)actualLines.size(); i++) {
98         actualLines[i].erase(actualLines[i].find_last_not_of(" ") + 1);
99     }
100 
101     for (int y = 0; y < (int)expectLines.size(); y++) {
102         expectLines[y].erase(expectLines[y].find_last_not_of(" ") + 1);
103     }
104     auto actual = actualLines.begin();
105     auto expect = expectLines.begin();
106     EXPECT_EQ(actualLines.size(), expectLines.size());
107 
108     while (actual != actualLines.end() and expect != expectLines.end() and !HasFailure()) {
109         EXPECT_STREQ(actual->c_str(), expect->c_str());
110         actual++;
111         expect++;
112     }
113     return !HasFailure();
114 }
115 
116 /**
117  * @tc.name: TestParseOption
118  * @tc.desc:
119  * @tc.type: FUNC
120  */
121 HWTEST_F(SubCommandReportTest, TestParseOption, TestSize.Level1)
122 {
123     SubCommandReport mSubCommandReport;
124     std::vector<std::string> args;
125     args = {"-i"};
126     EXPECT_EQ(mSubCommandReport.ParseOption(args), false);
127     args = {"-o"};
128     EXPECT_EQ(mSubCommandReport.ParseOption(args), false);
129     args = {"--diff"};
130     EXPECT_EQ(mSubCommandReport.ParseOption(args), false);
131     args = {"--sort"};
132     EXPECT_EQ(mSubCommandReport.ParseOption(args), false);
133     args = {"--symbol-dir"};
134     EXPECT_EQ(mSubCommandReport.ParseOption(args), false);
135     args = {"--limit-percent"};
136     EXPECT_EQ(mSubCommandReport.ParseOption(args), false);
137     args = {"-s"};
138     EXPECT_EQ(mSubCommandReport.ParseOption(args), true);
139     args = {"--call-stack"};
140     EXPECT_EQ(mSubCommandReport.ParseOption(args), true);
141     args = {"--call-stack-limit-percent"};
142     EXPECT_EQ(mSubCommandReport.ParseOption(args), false);
143     args = {"--comms"};
144     EXPECT_EQ(mSubCommandReport.ParseOption(args), false);
145     args = {"--pids"};
146     EXPECT_EQ(mSubCommandReport.ParseOption(args), false);
147     args = {"--tids"};
148     EXPECT_EQ(mSubCommandReport.ParseOption(args), false);
149     args = {"--dsos"};
150     EXPECT_EQ(mSubCommandReport.ParseOption(args), false);
151     args = {"--funcs"};
152     EXPECT_EQ(mSubCommandReport.ParseOption(args), false);
153     args = {"--from-dsos"};
154     EXPECT_EQ(mSubCommandReport.ParseOption(args), true);
155     args = {"--from-funcs"};
156     EXPECT_EQ(mSubCommandReport.ParseOption(args), true);
157     args = {"--proto"};
158     EXPECT_EQ(mSubCommandReport.ParseOption(args), true);
159     args = {"--json"};
160     EXPECT_EQ(mSubCommandReport.ParseOption(args), true);
161     args = {"--branch"};
162     EXPECT_EQ(mSubCommandReport.ParseOption(args), true);
163     args.clear();
164 }
165 
166 /**
167  * @tc.name: TestDumpOptions
168  * @tc.desc:
169  * @tc.type: FUNC
170  */
171 HWTEST_F(SubCommandReportTest, TestDumpOptions, TestSize.Level1)
172 {
173     SubCommandReport mSubCommandReport;
174     mSubCommandReport.DumpOptions();
175     EXPECT_EQ(1, 1);
176 }
177 
178 /**
179  * @tc.name: TestOnSubCommand_i
180  * @tc.desc:
181  * @tc.type: FUNC
182  */
183 HWTEST_F(SubCommandReportTest, TestOnSubCommand_i, TestSize.Level1)
184 {
185     StdoutRecord stdoutRecord;
186     stdoutRecord.Start();
187     const auto startTime = chrono::steady_clock::now();
188     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data"), true);
189     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
190         chrono::steady_clock::now() - startTime);
191     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
192 
193     std::string stringOut = stdoutRecord.Stop();
194     if (HasFailure()) {
195         printf("output:\n%s", stringOut.c_str());
196     }
197     std::string targetFile = RESOURCE_PATH + "report_test_i.txt";
198     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
199 }
200 
201 /**
202  * @tc.name: TestOnSubCommand_i1
203  * @tc.desc:
204  * @tc.type: FUNC
205  */
206 HWTEST_F(SubCommandReportTest, TestOnSubCommand_i1, TestSize.Level1)
207 {
208     StdoutRecord stdoutRecord;
209     stdoutRecord.Start();
210     const auto startTime = chrono::steady_clock::now();
211     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "perf1.data"), false);
212     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
213         chrono::steady_clock::now() - startTime);
214     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
215 
216     std::string stringOut = stdoutRecord.Stop();
217     if (HasFailure()) {
218         printf("output:\n%s", stringOut.c_str());
219     }
220     const std::string expectStr =
221         "Can not access data file /data/test/resource/testdata/perf1.data";
222     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
223 }
224 
225 /**
226  * @tc.name: TestOnSubCommand_i2
227  * @tc.desc:
228  * @tc.type: FUNC
229  */
230 HWTEST_F(SubCommandReportTest, TestOnSubCommand_i2, TestSize.Level1)
231 {
232     StdoutRecord stdoutRecord;
233     stdoutRecord.Start();
234     const auto startTime = chrono::steady_clock::now();
235     EXPECT_EQ(Command::DispatchCommand("report " + RESOURCE_PATH + "report_test.data -i"), false);
236     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
237         chrono::steady_clock::now() - startTime);
238     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
239 
240     std::string stringOut = stdoutRecord.Stop();
241     if (HasFailure()) {
242         printf("output:\n%s", stringOut.c_str());
243     }
244     const std::string expectStr = "option -i value missed";
245     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
246 }
247 
248 /**
249  * @tc.name: TestOnSubCommand_diff
250  * @tc.desc:
251  * @tc.type: FUNC
252  */
253 HWTEST_F(SubCommandReportTest, TestOnSubCommand_diff, TestSize.Level1)
254 {
255     StdoutRecord stdoutRecord;
256     stdoutRecord.Start();
257     const auto startTime = chrono::steady_clock::now();
258     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "perf1.data --diff " +
259                                        RESOURCE_PATH + "report_test.data"),
260               false);
261     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
262         chrono::steady_clock::now() - startTime);
263     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
264 
265     std::string stringOut = stdoutRecord.Stop();
266     if (HasFailure()) {
267         printf("output:\n%s", stringOut.c_str());
268     }
269     const std::string expectStr =
270         "Can not access data file /data/test/resource/testdata/perf1.data";
271     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
272 }
273 
274 /**
275  * @tc.name: TestOnSubCommand_Diff_Same
276  * @tc.desc:
277  * @tc.type: FUNC
278  */
279 HWTEST_F(SubCommandReportTest, TestOnSubCommand_Diff_Same, TestSize.Level1)
280 {
281     StdoutRecord stdoutRecord;
282     stdoutRecord.Start();
283     const auto startTime = chrono::steady_clock::now();
284 
285     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --diff " +
286                                        RESOURCE_PATH + "report_test.data"),
287               true);
288     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
289         chrono::steady_clock::now() - startTime);
290     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
291 
292     std::string stringOut = stdoutRecord.Stop();
293     if (HasFailure()) {
294         printf("output:\n%s", stringOut.c_str());
295     }
296     std::string targetFile = RESOURCE_PATH + "report_test_diff.txt";
297     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
298 }
299 
300 /**
301  * @tc.name: TestOnSubCommand_sort
302  * @tc.desc:
303  * @tc.type: FUNC
304  */
305 HWTEST_F(SubCommandReportTest, TestOnSubCommand_sort, TestSize.Level1)
306 {
307     StdoutRecord stdoutRecord;
308     stdoutRecord.Start();
309     const auto startTime = chrono::steady_clock::now();
310     EXPECT_EQ(
311         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --sort pid"),
312         true);
313     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
314         chrono::steady_clock::now() - startTime);
315     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
316 
317     std::string stringOut = stdoutRecord.Stop();
318     if (HasFailure()) {
319         printf("output:\n%s", stringOut.c_str());
320     }
321     const std::string expectStr = "100.00%  271445 1204";
322     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
323 }
324 
325 /**
326  * @tc.name: TestOnSubCommand_sort1
327  * @tc.desc:
328  * @tc.type: FUNC
329  */
330 HWTEST_F(SubCommandReportTest, TestOnSubCommand_sort1, TestSize.Level1)
331 {
332     StdoutRecord stdoutRecord;
333     stdoutRecord.Start();
334     const auto startTime = chrono::steady_clock::now();
335     EXPECT_EQ(
336         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --sort pid,tid"),
337         true);
338     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
339         chrono::steady_clock::now() - startTime);
340     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
341 
342     std::string stringOut = stdoutRecord.Stop();
343     if (HasFailure()) {
344         printf("output:\n%s", stringOut.c_str());
345     }
346     std::string targetFile = RESOURCE_PATH + "report_test_sort1.txt";
347     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
348 }
349 
350 /**
351  * @tc.name: TestOnSubCommand_sort2
352  * @tc.desc:
353  * @tc.type: FUNC
354  */
355 HWTEST_F(SubCommandReportTest, TestOnSubCommand_sort2, TestSize.Level1)
356 {
357     StdoutRecord stdoutRecord;
358     stdoutRecord.Start();
359     const auto startTime = chrono::steady_clock::now();
360     EXPECT_EQ(
361         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --sort func"),
362         true);
363     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
364         chrono::steady_clock::now() - startTime);
365     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
366 
367     std::string stringOut = stdoutRecord.Stop();
368     if (HasFailure()) {
369         printf("output:\n%s", stringOut.c_str());
370     }
371     std::string targetFile = RESOURCE_PATH + "report_test_sort2.txt";
372     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
373 }
374 
375 /**
376  * @tc.name: TestOnSubCommand_sort3
377  * @tc.desc:
378  * @tc.type: FUNC
379  */
380 HWTEST_F(SubCommandReportTest, TestOnSubCommand_sort3, TestSize.Level1)
381 {
382     StdoutRecord stdoutRecord;
383     stdoutRecord.Start();
384     const auto startTime = chrono::steady_clock::now();
385     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "perf1.data --sort pid"),
386               false);
387     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
388         chrono::steady_clock::now() - startTime);
389     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
390 
391     std::string stringOut = stdoutRecord.Stop();
392     if (HasFailure()) {
393         printf("output:\n%s", stringOut.c_str());
394     }
395     const std::string expectStr =
396         "Can not access data file /data/test/resource/testdata/perf1.data";
397     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
398 }
399 
400 /**
401  * @tc.name: TestOnSubCommand_sort4
402  * @tc.desc:
403  * @tc.type: FUNC
404  */
405 HWTEST_F(SubCommandReportTest, TestOnSubCommand_sort4, TestSize.Level1)
406 {
407     StdoutRecord stdoutRecord;
408     stdoutRecord.Start();
409     const auto startTime = chrono::steady_clock::now();
410     EXPECT_EQ(
411         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --sort pids"),
412         false);
413     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
414         chrono::steady_clock::now() - startTime);
415     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
416 
417     std::string stringOut = stdoutRecord.Stop();
418     if (HasFailure()) {
419         printf("output:\n%s", stringOut.c_str());
420     }
421     const std::string expectStr = "unknown sort key name 'pids'";
422     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
423 }
424 
425 /**
426  * @tc.name: TestOnSubCommand_symbol
427  * @tc.desc:
428  * @tc.type: FUNC
429  */
430 HWTEST_F(SubCommandReportTest, TestOnSubCommand_symbol, TestSize.Level1)
431 {
432     StdoutRecord stdoutRecord;
433     stdoutRecord.Start();
434     const auto startTime = chrono::steady_clock::now();
435     EXPECT_EQ(
436         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --symbol-dir ./"),
437         true);
438     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
439         chrono::steady_clock::now() - startTime);
440     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
441 
442     std::string stringOut = stdoutRecord.Stop();
443     if (HasFailure()) {
444         printf("output:\n%s", stringOut.c_str());
445     }
446     std::string targetFile = RESOURCE_PATH + "report_test_symbol.txt";
447     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
448 }
449 
450 /**
451  * @tc.name: TestOnSubCommand_limit
452  * @tc.desc:
453  * @tc.type: FUNC
454  */
455 HWTEST_F(SubCommandReportTest, TestOnSubCommand_limit, TestSize.Level1)
456 {
457     StdoutRecord stdoutRecord;
458     stdoutRecord.Start();
459     const auto startTime = chrono::steady_clock::now();
460     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH +
461                                        "report_test.data --limit-percent 5"),
462               true);
463     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
464         chrono::steady_clock::now() - startTime);
465     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
466 
467     std::string stringOut = stdoutRecord.Stop();
468     if (HasFailure()) {
469         printf("output:\n%s", stringOut.c_str());
470     }
471     std::string targetFile = RESOURCE_PATH + "report_test_limit.txt";
472     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
473 }
474 
475 /**
476  * @tc.name: TestOnSubCommand_limit1
477  * @tc.desc:
478  * @tc.type: FUNC
479  */
480 HWTEST_F(SubCommandReportTest, TestOnSubCommand_limit1, TestSize.Level1)
481 {
482     StdoutRecord stdoutRecord;
483     stdoutRecord.Start();
484     const auto startTime = chrono::steady_clock::now();
485     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH +
486                                        "report_test.data --limit-percent 1"),
487               true);
488     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
489         chrono::steady_clock::now() - startTime);
490     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
491 
492     std::string stringOut = stdoutRecord.Stop();
493     if (HasFailure()) {
494         printf("output:\n%s", stringOut.c_str());
495     }
496     std::string targetFile = RESOURCE_PATH + "report_test_limit1.txt";
497     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
498 }
499 
500 /**
501  * @tc.name: TestOnSubCommand_limit2
502  * @tc.desc:
503  * @tc.type: FUNC
504  */
505 HWTEST_F(SubCommandReportTest, TestOnSubCommand_limit2, TestSize.Level1)
506 {
507     StdoutRecord stdoutRecord;
508     stdoutRecord.Start();
509     const auto startTime = chrono::steady_clock::now();
510     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH +
511                                        "report_test.data --limit-percent 99"),
512               true);
513     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
514         chrono::steady_clock::now() - startTime);
515     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
516 
517     std::string stringOut = stdoutRecord.Stop();
518     if (HasFailure()) {
519         printf("output:\n%s", stringOut.c_str());
520     }
521     const std::string expectStr = "kernel.kallsyms";
522     EXPECT_EQ(FindExpectStr(stringOut, expectStr), false);
523 }
524 
525 /**
526  * @tc.name: TestOnSubCommand_limit3
527  * @tc.desc:
528  * @tc.type: FUNC
529  */
530 HWTEST_F(SubCommandReportTest, TestOnSubCommand_limit3, TestSize.Level1)
531 {
532     StdoutRecord stdoutRecord;
533     stdoutRecord.Start();
534     const auto startTime = chrono::steady_clock::now();
535     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH +
536                                        "report_test.data --limit-percent -1"),
537               false);
538     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
539         chrono::steady_clock::now() - startTime);
540     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
541 
542     std::string stringOut = stdoutRecord.Stop();
543     if (HasFailure()) {
544         printf("output:\n%s", stringOut.c_str());
545     }
546     const std::string expectStr = "head limit error. must in (0 <= limit < 100)";
547     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
548 }
549 
550 /**
551  * @tc.name: TestOnSubCommand_limit4
552  * @tc.desc:
553  * @tc.type: FUNC
554  */
555 HWTEST_F(SubCommandReportTest, TestOnSubCommand_limit4, TestSize.Level1)
556 {
557     StdoutRecord stdoutRecord;
558     stdoutRecord.Start();
559     const auto startTime = chrono::steady_clock::now();
560     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH +
561                                        "report_test.data --limit-percent 101"),
562               false);
563     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
564         chrono::steady_clock::now() - startTime);
565     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
566 
567     std::string stringOut = stdoutRecord.Stop();
568     if (HasFailure()) {
569         printf("output:\n%s", stringOut.c_str());
570     }
571     const std::string expectStr = "head limit error. must in (0 <= limit < 100)";
572     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
573 }
574 
575 /**
576  * @tc.name: TestOnSubCommand_callstack
577  * @tc.desc:
578  * @tc.type: FUNC
579  */
580 HWTEST_F(SubCommandReportTest, TestOnSubCommand_callstack, TestSize.Level1)
581 {
582     StdoutRecord stdoutRecord;
583     stdoutRecord.Start();
584     const auto startTime = chrono::steady_clock::now();
585     EXPECT_EQ(
586         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --call-stack"),
587         true);
588     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
589         chrono::steady_clock::now() - startTime);
590     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
591 
592     std::string stringOut = stdoutRecord.Stop();
593     if (HasFailure()) {
594         printf("output:\n%s", stringOut.c_str());
595     }
596     std::string targetFile = RESOURCE_PATH + "report_test_callstack.txt";
597     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
598 }
599 
600 /**
601  * @tc.name: TestOnSubCommand_comms
602  * @tc.desc:
603  * @tc.type: FUNC
604  */
605 HWTEST_F(SubCommandReportTest, TestOnSubCommand_comms, TestSize.Level1)
606 {
607     StdoutRecord stdoutRecord;
608     stdoutRecord.Start();
609     const auto startTime = chrono::steady_clock::now();
610     EXPECT_EQ(
611         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --comms hiperf"),
612         true);
613     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
614         chrono::steady_clock::now() - startTime);
615     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
616 
617     std::string stringOut = stdoutRecord.Stop();
618     if (HasFailure()) {
619         printf("output:\n%s", stringOut.c_str());
620     }
621     std::string targetFile = RESOURCE_PATH + "report_test_i.txt";
622     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
623 }
624 
625 /**
626  * @tc.name: TestOnSubCommand_pids
627  * @tc.desc:
628  * @tc.type: FUNC
629  */
630 HWTEST_F(SubCommandReportTest, TestOnSubCommand_pids, TestSize.Level1)
631 {
632     StdoutRecord stdoutRecord;
633     stdoutRecord.Start();
634     const auto startTime = chrono::steady_clock::now();
635     EXPECT_EQ(
636         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --pids 1204"),
637         true);
638     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
639         chrono::steady_clock::now() - startTime);
640     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
641 
642     std::string stringOut = stdoutRecord.Stop();
643     if (HasFailure()) {
644         printf("output:\n%s", stringOut.c_str());
645     }
646     std::string targetFile = RESOURCE_PATH + "report_test_i.txt";
647     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
648 }
649 
650 /**
651  * @tc.name: TestOnSubCommand_pids1
652  * @tc.desc:
653  * @tc.type: FUNC
654  */
655 HWTEST_F(SubCommandReportTest, TestOnSubCommand_pids1, TestSize.Level1)
656 {
657     StdoutRecord stdoutRecord;
658     stdoutRecord.Start();
659     const auto startTime = chrono::steady_clock::now();
660     EXPECT_EQ(
661         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --pids 485"),
662         true);
663     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
664         chrono::steady_clock::now() - startTime);
665     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
666 
667     std::string stringOut = stdoutRecord.Stop();
668     if (HasFailure()) {
669         printf("output:\n%s", stringOut.c_str());
670     }
671     std::string targetFile = RESOURCE_PATH + "report_test_tids1.txt";
672     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
673 }
674 
675 /**
676  * @tc.name: TestOnSubCommand_pids2
677  * @tc.desc:
678  * @tc.type: FUNC
679  */
680 HWTEST_F(SubCommandReportTest, TestOnSubCommand_pids2, TestSize.Level1)
681 {
682     StdoutRecord stdoutRecord;
683     stdoutRecord.Start();
684     const auto startTime = chrono::steady_clock::now();
685     EXPECT_EQ(
686         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --pids 11111"),
687         true);
688     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
689         chrono::steady_clock::now() - startTime);
690     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
691 
692     std::string stringOut = stdoutRecord.Stop();
693     if (HasFailure()) {
694         printf("output:\n%s", stringOut.c_str());
695     }
696     std::string targetFile = RESOURCE_PATH + "report_test_tids1.txt";
697     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
698 }
699 
700 /**
701  * @tc.name: TestOnSubCommand_pids3
702  * @tc.desc:
703  * @tc.type: FUNC
704  */
705 HWTEST_F(SubCommandReportTest, TestOnSubCommand_pids3, TestSize.Level1)
706 {
707     StdoutRecord stdoutRecord;
708     stdoutRecord.Start();
709     const auto startTime = chrono::steady_clock::now();
710     EXPECT_EQ(
711         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --pids -106"),
712         false);
713     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
714         chrono::steady_clock::now() - startTime);
715     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
716 
717     std::string stringOut = stdoutRecord.Stop();
718     if (HasFailure()) {
719         printf("output:\n%s", stringOut.c_str());
720     }
721     const std::string expectStr = "error number for pid";
722     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
723 }
724 
725 /**
726  * @tc.name: TestOnSubCommand_tids
727  * @tc.desc:
728  * @tc.type: FUNC
729  */
730 HWTEST_F(SubCommandReportTest, TestOnSubCommand_tids, TestSize.Level1)
731 {
732     StdoutRecord stdoutRecord;
733     stdoutRecord.Start();
734     const auto startTime = chrono::steady_clock::now();
735     EXPECT_EQ(
736         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --tids 1205"),
737         true);
738     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
739         chrono::steady_clock::now() - startTime);
740     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
741 
742     std::string stringOut = stdoutRecord.Stop();
743     if (HasFailure()) {
744         printf("output:\n%s", stringOut.c_str());
745     }
746     std::string targetFile = RESOURCE_PATH + "report_test_tids.txt";
747     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
748 }
749 
750 /**
751  * @tc.name: TestOnSubCommand_tids1
752  * @tc.desc:
753  * @tc.type: FUNC
754  */
755 HWTEST_F(SubCommandReportTest, TestOnSubCommand_tids1, TestSize.Level1)
756 {
757     StdoutRecord stdoutRecord;
758     stdoutRecord.Start();
759     const auto startTime = chrono::steady_clock::now();
760     EXPECT_EQ(
761         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --tids 905"),
762         true);
763     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
764         chrono::steady_clock::now() - startTime);
765     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
766 
767     std::string stringOut = stdoutRecord.Stop();
768     if (HasFailure()) {
769         printf("output:\n%s", stringOut.c_str());
770     }
771     std::string targetFile = RESOURCE_PATH + "report_test_tids1.txt";
772     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
773 }
774 
775 /**
776  * @tc.name: TestOnSubCommand_tids2
777  * @tc.desc:
778  * @tc.type: FUNC
779  */
780 HWTEST_F(SubCommandReportTest, TestOnSubCommand_tids2, TestSize.Level1)
781 {
782     StdoutRecord stdoutRecord;
783     stdoutRecord.Start();
784     const auto startTime = chrono::steady_clock::now();
785     EXPECT_EQ(
786         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --tids 11111"),
787         true);
788     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
789         chrono::steady_clock::now() - startTime);
790     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
791 
792     std::string stringOut = stdoutRecord.Stop();
793     if (HasFailure()) {
794         printf("output:\n%s", stringOut.c_str());
795     }
796     std::string targetFile = RESOURCE_PATH + "report_test_tids1.txt";
797     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
798 }
799 
800 /**
801  * @tc.name: TestOnSubCommand_tids3
802  * @tc.desc:
803  * @tc.type: FUNC
804  */
805 HWTEST_F(SubCommandReportTest, TestOnSubCommand_tids3, TestSize.Level1)
806 {
807     StdoutRecord stdoutRecord;
808     stdoutRecord.Start();
809     const auto startTime = chrono::steady_clock::now();
810     EXPECT_EQ(
811         Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --tids -109"),
812         false);
813     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
814         chrono::steady_clock::now() - startTime);
815     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
816 
817     std::string stringOut = stdoutRecord.Stop();
818     if (HasFailure()) {
819         printf("output:\n%s", stringOut.c_str());
820     }
821     const std::string expectStr = "error number for tid";
822     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
823 }
824 
825 /**
826  * @tc.name: TestOnSubCommand_dsos
827  * @tc.desc:
828  * @tc.type: FUNC
829  */
830 HWTEST_F(SubCommandReportTest, TestOnSubCommand_dsos, TestSize.Level1)
831 {
832     StdoutRecord stdoutRecord;
833     stdoutRecord.Start();
834     const auto startTime = chrono::steady_clock::now();
835     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH +
836                                        "report_test.data --dsos [kernel.kallsyms]"),
837               true);
838     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
839         chrono::steady_clock::now() - startTime);
840     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
841 
842     std::string stringOut = stdoutRecord.Stop();
843     if (HasFailure()) {
844         printf("output:\n%s", stringOut.c_str());
845     }
846     std::string targetFile = RESOURCE_PATH + "report_test_dsos.txt";
847     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
848 }
849 
850 /**
851  * @tc.name: TestOnSubCommand_dsos1
852  * @tc.desc:
853  * @tc.type: FUNC
854  */
855 HWTEST_F(SubCommandReportTest, TestOnSubCommand_dsos1, TestSize.Level1)
856 {
857     StdoutRecord stdoutRecord;
858     stdoutRecord.Start();
859     const auto startTime = chrono::steady_clock::now();
860     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH +
861                                        "report_test.data --dsos /system/lib/libcamera.so"),
862               true);
863     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
864         chrono::steady_clock::now() - startTime);
865     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
866 
867     std::string stringOut = stdoutRecord.Stop();
868     if (HasFailure()) {
869         printf("output:\n%s", stringOut.c_str());
870     }
871     std::string targetFile = RESOURCE_PATH + "report_test_tids1.txt";
872     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
873 }
874 
875 /**
876  * @tc.name: TestOnSubCommand_dsos2
877  * @tc.desc:
878  * @tc.type: FUNC
879  */
880 HWTEST_F(SubCommandReportTest, TestOnSubCommand_dsos2, TestSize.Level1)
881 {
882     StdoutRecord stdoutRecord;
883     stdoutRecord.Start();
884     const auto startTime = chrono::steady_clock::now();
885     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --dso"),
886               false);
887     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
888         chrono::steady_clock::now() - startTime);
889     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
890 
891     std::string stringOut = stdoutRecord.Stop();
892     if (HasFailure()) {
893         printf("output:\n%s", stringOut.c_str());
894     }
895     const std::string expectStr = "unknown option";
896     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
897 }
898 
899 /**
900  * @tc.name: TestOnSubCommand_funcs
901  * @tc.desc:
902  * @tc.type: FUNC
903  */
904 HWTEST_F(SubCommandReportTest, TestOnSubCommand_funcs, TestSize.Level1)
905 {
906     StdoutRecord stdoutRecord;
907     stdoutRecord.Start();
908     const auto startTime = chrono::steady_clock::now();
909     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH +
910                                        "report_test.data --funcs finish_task_switch"),
911               true);
912     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
913         chrono::steady_clock::now() - startTime);
914     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
915 
916     std::string stringOut = stdoutRecord.Stop();
917     if (HasFailure()) {
918         printf("output:\n%s", stringOut.c_str());
919     }
920     std::string targetFile = RESOURCE_PATH + "report_test_funcs.txt";
921     EXPECT_EQ(FileCompare(stringOut, targetFile), true);
922 }
923 
924 /**
925  * @tc.name: TestOnSubCommand_funcs1
926  * @tc.desc:
927  * @tc.type: FUNC
928  */
929 HWTEST_F(SubCommandReportTest, TestOnSubCommand_funcs1, TestSize.Level1)
930 {
931     StdoutRecord stdoutRecord;
932     stdoutRecord.Start();
933     const auto startTime = chrono::steady_clock::now();
934     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --func"),
935               false);
936     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
937         chrono::steady_clock::now() - startTime);
938     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
939 
940     std::string stringOut = stdoutRecord.Stop();
941     if (HasFailure()) {
942         printf("output:\n%s", stringOut.c_str());
943     }
944     const std::string expectStr = "unknown option";
945     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
946 }
947 
948 /**
949  * @tc.name: TestOnSubCommand_json
950  * @tc.desc:
951  * @tc.type: FUNC
952  */
953 HWTEST_F(SubCommandReportTest, TestOnSubCommand_json, TestSize.Level1)
954 {
955     StdoutRecord stdoutRecord;
956     stdoutRecord.Start();
957     const auto startTime = chrono::steady_clock::now();
958     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --json"),
959               true);
960     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
961         chrono::steady_clock::now() - startTime);
962     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
963 
964     std::string stringOut = stdoutRecord.Stop();
965     if (HasFailure()) {
966         printf("output:\n%s", stringOut.c_str());
967     }
968     const std::string expectStr = "report will save at 'perf.json'";
969     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
970 }
971 
972 /**
973  * @tc.name: TestOnSubCommand_json1
974  * @tc.desc:
975  * @tc.type: FUNC
976  */
977 HWTEST_F(SubCommandReportTest, TestOnSubCommand_json1, TestSize.Level1)
978 {
979     StdoutRecord stdoutRecord;
980     stdoutRecord.Start();
981     const auto startTime = chrono::steady_clock::now();
982     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "perf1.data --json"), false);
983     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
984         chrono::steady_clock::now() - startTime);
985     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
986 
987     std::string stringOut = stdoutRecord.Stop();
988     if (HasFailure()) {
989         printf("output:\n%s", stringOut.c_str());
990     }
991     const std::string expectStr =
992         "Can not access data file /data/test/resource/testdata/perf1.data";
993     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
994 }
995 
996 /**
997  * @tc.name: TestOnSubCommand_proto
998  * @tc.desc:
999  * @tc.type: FUNC
1000  */
1001 HWTEST_F(SubCommandReportTest, TestOnSubCommand_proto, TestSize.Level1)
1002 {
1003     StdoutRecord stdoutRecord;
1004     stdoutRecord.Start();
1005     const auto startTime = chrono::steady_clock::now();
1006     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data --proto"),
1007               true);
1008     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1009         chrono::steady_clock::now() - startTime);
1010     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
1011 
1012     std::string stringOut = stdoutRecord.Stop();
1013     if (HasFailure()) {
1014         printf("output:\n%s", stringOut.c_str());
1015     }
1016     const std::string expectStr = "create proto buf file succeed";
1017     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1018 }
1019 
1020 /**
1021  * @tc.name: TestOnSubCommand_proto1
1022  * @tc.desc:
1023  * @tc.type: FUNC
1024  */
1025 HWTEST_F(SubCommandReportTest, TestOnSubCommand_proto1, TestSize.Level1)
1026 {
1027     StdoutRecord stdoutRecord;
1028     stdoutRecord.Start();
1029     const auto startTime = chrono::steady_clock::now();
1030     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "perf1.data --proto"), false);
1031     const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1032         chrono::steady_clock::now() - startTime);
1033     EXPECT_LE(costMs.count(), DEFAULT_RUN_TIMEOUT_MS);
1034 
1035     std::string stringOut = stdoutRecord.Stop();
1036     if (HasFailure()) {
1037         printf("output:\n%s", stringOut.c_str());
1038     }
1039     const std::string expectStr =
1040         "Can not access data file /data/test/resource/testdata/perf1.data";
1041     EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1042 }
1043 
1044 /**
1045  * @tc.name: TestLoadPerfData
1046  * @tc.desc:
1047  * @tc.type: FUNC
1048  */
1049 HWTEST_F(SubCommandReportTest, TestLoadPerfData, TestSize.Level1)
1050 {
1051     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data -o " +
1052                                        RESOURCE_PATH + "perfnew2.data"),
1053               true);
1054     EXPECT_EQ(IsPath(RESOURCE_PATH + "report_test.data"), true);
1055 }
1056 
1057 /**
1058  * @tc.name: TestOutputReport
1059  * @tc.desc:
1060  * @tc.type: FUNC
1061  */
1062 HWTEST_F(SubCommandReportTest, TestOutputReport, TestSize.Level1)
1063 {
1064     EXPECT_EQ(Command::DispatchCommand("report -i " + RESOURCE_PATH + "report_test.data -o " +
1065                                        RESOURCE_PATH + "perfnew2.data"),
1066               true);
1067     EXPECT_EQ(IsPath(RESOURCE_PATH + "perfnew2.data"), true);
1068 }
1069 
1070 /**
1071  * @tc.name: TestVerifyOption
1072  * @tc.desc:
1073  * @tc.type: FUNC
1074  */
1075 HWTEST_F(SubCommandReportTest, TestVerifyOption, TestSize.Level1)
1076 {
1077     SubCommandReport mSubCommandReport;
1078     std::string recordFile;
1079     std::vector<std::string> args;
1080     args = {"report", "-i", RESOURCE_PATH + "/report_test.data", "--limit-percent", "60"};
1081     ASSERT_EQ(
1082         Option::GetOptionValue(args, "--limit-percent", mSubCommandReport.reportOption_.heatLimit_),
1083         true);
1084     ASSERT_EQ(Option::GetOptionValue(args, "-i", recordFile), true);
1085 
1086     EXPECT_EQ(mSubCommandReport.VerifyOption(), true);
1087 
1088     mSubCommandReport.reportOption_.heatLimit_ = 101.0;
1089     EXPECT_EQ(mSubCommandReport.VerifyOption(), false);
1090 }
1091 
1092 /**
1093  * @tc.name: TestVerifyDisplayOption
1094  * @tc.desc:
1095  * @tc.type: FUNC
1096  */
1097 HWTEST_F(SubCommandReportTest, TestVerifyDisplayOption, TestSize.Level1)
1098 {
1099     SubCommandReport mSubCommandReport;
1100     std::string recordFile;
1101     std::vector<std::string> args;
1102     args = {"report", "-i", RESOURCE_PATH + "report_test.data ", "--pids", "-1"};
1103     ASSERT_EQ(Option::GetOptionValue(args, "--pids", mSubCommandReport.reportOption_.displayPids_),
1104               true);
1105     ASSERT_EQ(Option::GetOptionValue(args, "-i", recordFile), true);
1106     EXPECT_EQ(mSubCommandReport.VerifyDisplayOption(), false);
1107 
1108     mSubCommandReport.reportOption_.displayPids_.clear();
1109     args = {"report -i " + RESOURCE_PATH + "report_test.data --pids "};
1110     EXPECT_EQ(mSubCommandReport.VerifyDisplayOption(), true);
1111 }
1112 } // namespace HiPerf
1113 } // namespace Developtools
1114 } // namespace OHOS
1115