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