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