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