1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hiperf_client_test.h"
17
18 #include <algorithm>
19 #include <chrono>
20 #include <cinttypes>
21 #include <thread>
22
23 #include "test_utilities.h"
24 #include "utilities.h"
25
26 using namespace testing::ext;
27 using namespace std;
28 namespace OHOS {
29 namespace Developtools {
30 namespace HiPerf {
31 const int DEFAULT_DURATION_TIME = 10;
32 class HiperfClientTest : public testing::Test {
33 public:
34 static void SetUpTestCase(void);
35 static void TearDownTestCase(void);
36 void SetUp();
37 void TearDown();
38
39 static void TestCaseOption(const HiperfClient::RecordOption &opt);
40 };
41
SetUpTestCase()42 void HiperfClientTest::SetUpTestCase() {}
43
TearDownTestCase()44 void HiperfClientTest::TearDownTestCase()
45 {
46 DebugLogger::GetInstance()->Reset();
47 }
48
SetUp()49 void HiperfClientTest::SetUp() {}
50
TearDown()51 void HiperfClientTest::TearDown()
52 {
53 }
54
55 /**
56 * @tc.name:
57 * @tc.desc: record
58 * @tc.type: FUNC
59 */
60 HWTEST_F(HiperfClientTest, NoPara, TestSize.Level0)
61 {
62 StdoutRecord stdoutRecord;
63 stdoutRecord.Start();
64
65 HiperfClient::Client myHiperf;
66 myHiperf.SetDebugMode();
67 ASSERT_TRUE(myHiperf.Start());
68
69 ASSERT_TRUE(myHiperf.Pause());
70 std::this_thread::sleep_for(1s);
71
72 ASSERT_TRUE(myHiperf.Resume());
73 std::this_thread::sleep_for(1s);
74
75 ASSERT_TRUE(myHiperf.Stop());
76
77 stdoutRecord.Stop();
78 }
79
80 HWTEST_F(HiperfClientTest, OutDir, TestSize.Level1)
81 {
82 StdoutRecord stdoutRecord;
83 stdoutRecord.Start();
84
85 HiperfClient::Client myHiperf("/data/local/tmp/");
86 ASSERT_EQ(myHiperf.GetOutputDir(), "/data/local/tmp/");
87 myHiperf.SetDebugMode();
88 ASSERT_TRUE(myHiperf.Start());
89
90 ASSERT_TRUE(myHiperf.Pause());
91 std::this_thread::sleep_for(1s);
92
93 ASSERT_TRUE(myHiperf.Resume());
94 std::this_thread::sleep_for(1s);
95
96 ASSERT_TRUE(myHiperf.Stop());
97
98 stdoutRecord.Stop();
99 }
100
101 HWTEST_F(HiperfClientTest, DebugMuchMode, TestSize.Level0)
102 {
103 StdoutRecord stdoutRecord;
104 stdoutRecord.Start();
105
106 HiperfClient::Client myHiperf;
107 myHiperf.SetDebugMuchMode();
108 ASSERT_TRUE(myHiperf.Start());
109
110 ASSERT_TRUE(myHiperf.Pause());
111 std::this_thread::sleep_for(1s);
112
113 ASSERT_TRUE(myHiperf.Resume());
114 std::this_thread::sleep_for(1s);
115
116 ASSERT_TRUE(myHiperf.Stop());
117
118 stdoutRecord.Stop();
119 }
120
121 HWTEST_F(HiperfClientTest, EnableHilog, TestSize.Level1)
122 {
123 StdoutRecord stdoutRecord;
124 stdoutRecord.Start();
125
126 HiperfClient::Client myHiperf;
127 myHiperf.SetDebugMode();
128 myHiperf.EnableHilog();
129 ASSERT_TRUE(myHiperf.Start());
130
131 ASSERT_TRUE(myHiperf.Pause());
132 std::this_thread::sleep_for(1s);
133
134 ASSERT_TRUE(myHiperf.Resume());
135 std::this_thread::sleep_for(1s);
136
137 ASSERT_TRUE(myHiperf.Stop());
138
139 stdoutRecord.Stop();
140 }
141
142 HWTEST_F(HiperfClientTest, Prepare, TestSize.Level0)
143 {
144 StdoutRecord stdoutRecord;
145 stdoutRecord.Start();
146 HiperfClient::RecordOption opt;
147 opt.SetTargetSystemWide(true);
148
149 HiperfClient::Client myHiperf("/data/local/tmp/");
150 ASSERT_TRUE(myHiperf.PrePare(opt));
151 std::this_thread::sleep_for(1s);
152
153 ASSERT_TRUE(myHiperf.StartRun());
154 std::this_thread::sleep_for(1s);
155
156 ASSERT_TRUE(myHiperf.Stop());
157
158 stdoutRecord.Stop();
159 }
160
161 HWTEST_F(HiperfClientTest, GetCommandPath, TestSize.Level1)
162 {
163 StdoutRecord stdoutRecord;
164 stdoutRecord.Start();
165
166 HiperfClient::Client myHiperf("/data/local/tmp/");
167 ASSERT_EQ(myHiperf.GetCommandPath().empty(), false);
168
169 stdoutRecord.Stop();
170 }
171
TestCaseOption(const HiperfClient::RecordOption & opt)172 void HiperfClientTest::TestCaseOption(const HiperfClient::RecordOption &opt)
173 {
174 StdoutRecord stdoutRecord;
175 stdoutRecord.Start();
176 HiperfClient::Client myHiperf;
177 myHiperf.SetDebugMode();
178
179 ASSERT_TRUE(myHiperf.IsReady());
180 ASSERT_TRUE(myHiperf.Start(opt));
181
182 bool retPause = true;
183 bool retResume = true;
184 bool retStop = true;
185 if (!myHiperf.Pause()) {
186 retPause = false;
187 }
188 std::this_thread::sleep_for(1s);
189
190 if (!myHiperf.Resume()) {
191 retResume = false;
192 }
193 std::this_thread::sleep_for(1s);
194
195 if (!myHiperf.Stop()) {
196 retStop = false;
197 }
198
199 ASSERT_TRUE(retPause);
200 ASSERT_TRUE(retResume);
201 ASSERT_TRUE(retStop);
202
203 stdoutRecord.Stop();
204 }
205
206 HWTEST_F(HiperfClientTest, SetTargetSystemWide, TestSize.Level0)
207 {
208 HiperfClient::RecordOption opt;
209 opt.SetTargetSystemWide(true);
210
211 TestCaseOption(opt);
212 }
213
214 HWTEST_F(HiperfClientTest, SetCompressData, TestSize.Level2)
215 {
216 HiperfClient::RecordOption opt;
217 std::vector<pid_t> selectPids = {getpid()};
218 opt.SetSelectPids(selectPids);
219 opt.SetCompressData(true);
220 TestCaseOption(opt);
221 }
222
223 HWTEST_F(HiperfClientTest, SetSelectCpus, TestSize.Level1)
224 {
225 HiperfClient::RecordOption opt;
226 std::vector<pid_t> selectPids = {getpid()};
227 opt.SetSelectPids(selectPids);
228 std::vector<int> cpus = {0, 1};
229 opt.SetSelectCpus(cpus);
230
231 TestCaseOption(opt);
232 }
233
234 HWTEST_F(HiperfClientTest, SetTimeStopSec, TestSize.Level2)
235 {
236 HiperfClient::RecordOption opt;
237 std::vector<pid_t> selectPids = {getpid()};
238 opt.SetSelectPids(selectPids);
239 opt.SetTimeStopSec(40);
240
241 HiperfClient::Client myHiperf;
242 ASSERT_TRUE(myHiperf.IsReady());
243 ASSERT_TRUE(myHiperf.Start(opt));
244 }
245
246 HWTEST_F(HiperfClientTest, SetFrequency, TestSize.Level2)
247 {
248 HiperfClient::RecordOption opt;
249 std::vector<pid_t> selectPids = {getpid()};
250 opt.SetSelectPids(selectPids);
251 opt.SetFrequency(500);
252
253 TestCaseOption(opt);
254 }
255
256 HWTEST_F(HiperfClientTest, SetPeriod, TestSize.Level1)
257 {
258 HiperfClient::RecordOption opt;
259 std::vector<pid_t> selectPids = {getpid()};
260 opt.SetSelectPids(selectPids);
261 opt.SetPeriod(3);
262
263 TestCaseOption(opt);
264 }
265
266 HWTEST_F(HiperfClientTest, SetSelectEvents, TestSize.Level1)
267 {
268 HiperfClient::RecordOption opt;
269 std::vector<pid_t> selectPids = {getpid()};
270 opt.SetSelectPids(selectPids);
271 std::vector<std::string> selectEvents = {"hw-cpu-cycles:k"};
272 opt.SetSelectEvents(selectEvents);
273
274 TestCaseOption(opt);
275 }
276
277 HWTEST_F(HiperfClientTest, SetSelectGroups, TestSize.Level2)
278 {
279 HiperfClient::RecordOption opt;
280 std::vector<pid_t> selectPids = {getpid()};
281 opt.SetSelectPids(selectPids);
282 std::vector<std::string> selectEvents = {"hw-cpu-cycles:u"};
283 opt.SetSelectGroups(selectEvents);
284 TestCaseOption(opt);
285 }
286
287 HWTEST_F(HiperfClientTest, SetNoInherit, TestSize.Level2)
288 {
289 HiperfClient::RecordOption opt;
290 std::vector<pid_t> selectPids = {getpid()};
291 opt.SetSelectPids(selectPids);
292 opt.SetNoInherit(true);
293
294 TestCaseOption(opt);
295 }
296
297 HWTEST_F(HiperfClientTest, SetSelectPids, TestSize.Level0)
298 {
299 HiperfClient::RecordOption opt;
300 std::vector<pid_t> selectPids = {getpid()};
301 opt.SetSelectPids(selectPids);
302
303 TestCaseOption(opt);
304 }
305
306 HWTEST_F(HiperfClientTest, SetCallStackSamplingConfigs, TestSize.Level2)
307 {
308 HiperfClient::RecordOption opt;
309 std::vector<pid_t> selectPids = {getpid()};
310 opt.SetSelectPids(selectPids);
311 opt.SetCallStackSamplingConfigs(1);
312
313 HiperfClient::Client myHiperf;
314 ASSERT_TRUE(myHiperf.IsReady());
315 ASSERT_TRUE(myHiperf.Start(opt));
316 }
317
318 HWTEST_F(HiperfClientTest, SetSelectTids, TestSize.Level1)
319 {
320 HiperfClient::RecordOption opt;
321 std::vector<pid_t> selectTids = {gettid()};
322 opt.SetSelectTids(selectTids);
323
324 TestCaseOption(opt);
325 }
326
327 HWTEST_F(HiperfClientTest, SetExcludePerf, TestSize.Level2)
328 {
329 HiperfClient::RecordOption opt;
330 opt.SetTargetSystemWide(true);
331 opt.SetExcludePerf(true);
332
333 TestCaseOption(opt);
334 }
335
336 HWTEST_F(HiperfClientTest, SetCpuPercent, TestSize.Level1)
337 {
338 HiperfClient::RecordOption opt;
339 std::vector<pid_t> selectPids = {getpid()};
340 opt.SetSelectPids(selectPids);
341 opt.SetCpuPercent(50);
342
343 TestCaseOption(opt);
344 }
345
346 HWTEST_F(HiperfClientTest, SetOffCPU, TestSize.Level1)
347 {
348 HiperfClient::RecordOption opt;
349 std::vector<pid_t> selectPids = {getpid()};
350 opt.SetSelectPids(selectPids);
351 opt.SetOffCPU(true);
352
353 TestCaseOption(opt);
354 }
355
356 HWTEST_F(HiperfClientTest, SetCallStack, TestSize.Level1)
357 {
358 HiperfClient::RecordOption opt;
359 std::vector<pid_t> selectPids = {getpid()};
360 opt.SetSelectPids(selectPids);
361 opt.SetCallGraph("fp");
362
363 TestCaseOption(opt);
364 }
365
366 HWTEST_F(HiperfClientTest, SetDelayUnwind, TestSize.Level1)
367 {
368 HiperfClient::RecordOption opt;
369 std::vector<pid_t> selectPids = {getpid()};
370 opt.SetSelectPids(selectPids);
371 opt.SetDelayUnwind(true);
372
373 TestCaseOption(opt);
374 }
375
376 HWTEST_F(HiperfClientTest, SetDisableUnwind, TestSize.Level2)
377 {
378 HiperfClient::RecordOption opt;
379 std::vector<pid_t> selectPids = {getpid()};
380 opt.SetSelectPids(selectPids);
381 opt.SetDisableUnwind(true);
382
383 TestCaseOption(opt);
384 }
385
386 HWTEST_F(HiperfClientTest, SetDisableCallstackMerge, TestSize.Level1)
387 {
388 HiperfClient::RecordOption opt;
389 std::vector<pid_t> selectPids = {getpid()};
390 opt.SetSelectPids(selectPids);
391 opt.SetDisableCallstackMerge(true);
392
393 TestCaseOption(opt);
394 }
395
396 HWTEST_F(HiperfClientTest, SetOutputFilename, TestSize.Level0)
397 {
398 HiperfClient::RecordOption opt;
399 std::vector<pid_t> selectPids = {getpid()};
400 opt.SetSelectPids(selectPids);
401 opt.SetOutputFilename("perf.data.ut");
402
403 TestCaseOption(opt);
404 }
405
406 HWTEST_F(HiperfClientTest, SetSymbolDir, TestSize.Level1)
407 {
408 HiperfClient::RecordOption opt;
409 std::vector<pid_t> selectPids = {getpid()};
410 opt.SetSelectPids(selectPids);
411 opt.SetSymbolDir("/data/local/tmp/");
412
413 TestCaseOption(opt);
414 }
415
416 HWTEST_F(HiperfClientTest, SetDataLimit, TestSize.Level2)
417 {
418 HiperfClient::RecordOption opt;
419 std::vector<pid_t> selectPids = {getpid()};
420 opt.SetSelectPids(selectPids);
421 opt.SetDataLimit("100M");
422
423 TestCaseOption(opt);
424 }
425
426 HWTEST_F(HiperfClientTest, SetAppPackage, TestSize.Level0)
427 {
428 HiperfClient::RecordOption opt;
429 std::string testProcesses = "com.ohos.launcher";
430 if (!CheckTestApp(testProcesses)) {
431 testProcesses = "hiview";
432 }
433 opt.SetAppPackage(testProcesses);
434
435 TestCaseOption(opt);
436 }
437
438 HWTEST_F(HiperfClientTest, SetClockId, TestSize.Level2)
439 {
440 HiperfClient::RecordOption opt;
441 std::vector<pid_t> selectPids = {getpid()};
442 opt.SetSelectPids(selectPids);
443 opt.SetClockId("monotonic");
444
445 TestCaseOption(opt);
446 }
447
448 HWTEST_F(HiperfClientTest, SetMmapPages, TestSize.Level1)
449 {
450 HiperfClient::RecordOption opt;
451 std::vector<pid_t> selectPids = {getpid()};
452 opt.SetSelectPids(selectPids);
453 opt.SetMmapPages(64);
454
455 TestCaseOption(opt);
456 }
457
458 HWTEST_F(HiperfClientTest, SetReport, TestSize.Level1)
459 {
460 HiperfClient::RecordOption opt;
461 std::vector<pid_t> selectPids = {getpid()};
462 opt.SetSelectPids(selectPids);
463 opt.SetReport(true);
464
465 TestCaseOption(opt);
466 }
467
468 HWTEST_F(HiperfClientTest, SetVecBranchSampleTypes, TestSize.Level2)
469 {
470 HiperfClient::RecordOption opt;
471 std::vector<pid_t> selectPids = {getpid()};
472 opt.SetSelectPids(selectPids);
473 opt.SetCallStackSamplingConfigs(1);
474 std::vector<std::string> branchSampleTypes = {"any"};
475 opt.SetVecBranchSampleTypes(branchSampleTypes);
476 HiperfClient::Client myHiperf;
477 ASSERT_TRUE(myHiperf.IsReady());
478 }
479
480 HWTEST_F(HiperfClientTest, Output, TestSize.Level1)
481 {
482 HiperfClient::RecordOption opt;
483 std::vector<std::string> process = {"hilogd"};
484 opt.SetTargetSystemWide(true);
485 opt.SetBackTrack(true);
486 opt.SetBackTrackSec(10); // 10 : 10s
487 opt.SetExcludeProcess(process);
488
489 HiperfClient::Client myHiperf("/data/local/tmp/");
490 EXPECT_TRUE(myHiperf.PrePare(opt));
491 std::this_thread::sleep_for(1s);
492 EXPECT_FALSE(myHiperf.Output());
493 std::this_thread::sleep_for(1s);
494 EXPECT_TRUE(myHiperf.Stop());
495 }
496
497 /**
498 * @tc.desc: SetCallStackSamplingConfigs(int duration)
499 * @tc.type: FUNC
500 */
501 HWTEST_F(HiperfClientTest, SetCallStackSamplingConfigsWithZeroDuration, TestSize.Level2)
502 {
503 HiperfClient::RecordOption opt;
504 std::vector<pid_t> selectPids = {getpid()};
505 opt.SetSelectPids(selectPids);
506 opt.SetCallStackSamplingConfigs(0);
507
508 bool hasTimeStopSec = false;
509 int actualDuration = 0;
510 for (size_t i = 0; i < opt.GetOptionVecString().size(); i++) {
511 if (opt.GetOptionVecString()[i] == "-d") {
512 hasTimeStopSec = true;
513 actualDuration = std::stoi(opt.GetOptionVecString()[i + 1]);
514 break;
515 }
516 }
517 ASSERT_TRUE(hasTimeStopSec);
518 ASSERT_EQ(actualDuration, DEFAULT_DURATION_TIME);
519 }
520
521 /**
522 * @tc.desc: SetOption(const std::string &name, bool enable)
523 * @tc.type: FUNC
524 */
525 HWTEST_F(HiperfClientTest, SetOptionRemoveExistingArgument, TestSize.Level2)
526 {
527 HiperfClient::RecordOption opt;
528 const std::string targetArg = "-a";
529
530 opt.SetOption(targetArg, true);
531 auto args = opt.GetOptionVecString();
532 ASSERT_TRUE(std::find(args.begin(), args.end(), targetArg) != args.end());
533
534 opt.SetOption(targetArg, false);
535 args = opt.GetOptionVecString();
536
537 auto it = std::find(args.begin(), args.end(), targetArg);
538 ASSERT_TRUE(it == args.end());
539 }
540
541 /**
542 * @tc.desc: SetOption(const std::string &name, const std::vector<int> &vInt)
543 * @tc.type: FUNC
544 */
545 HWTEST_F(HiperfClientTest, RemoveExistingOptionWithEmptyVectorOfInt, TestSize.Level2)
546 {
547 HiperfClient::RecordOption opt;
548 opt.SetOption("-c", std::vector<int>{1, 2, 3});
549
550 auto args = opt.GetOptionVecString();
551 ASSERT_EQ(args.size(), 2);
552 ASSERT_EQ(args[0], "-c");
553 ASSERT_EQ(args[1], "1,2,3");
554
555 opt.SetOption("-c", std::vector<int>{});
556
557 args = opt.GetOptionVecString();
558 auto it = std::find(args.begin(), args.end(), "-c");
559 ASSERT_EQ(it, args.end());
560 }
561
562 /**
563 * @tc.desc: SetOption(const std::string &name, const std::vector<int> &vInt)
564 * @tc.type: FUNC
565 */
566 HWTEST_F(HiperfClientTest, UpdateExistingOption, TestSize.Level2)
567 {
568 HiperfClient::RecordOption opt;
569 opt.SetOption("-c", std::vector<int>{1, 2});
570
571 auto args = opt.GetOptionVecString();
572 ASSERT_EQ(args.size(), 2);
573 ASSERT_EQ(args[0], "-c");
574 ASSERT_EQ(args[1], "1,2");
575
576 opt.SetOption("-c", std::vector<int>{3, 4, 5});
577
578 args = opt.GetOptionVecString();
579 ASSERT_EQ(args.size(), 2);
580 ASSERT_EQ(args[0], "-c");
581 ASSERT_EQ(args[1], "3,4,5");
582 }
583
584 /**
585 * @tc.desc: SetOption(const std::string &name, const std::string &str)
586 * @tc.type: FUNC
587 */
588 HWTEST_F(HiperfClientTest, RemoveExistingOptionWithEmptyString, TestSize.Level2)
589 {
590 HiperfClient::RecordOption opt;
591 opt.SetOption("-o", std::string("perf.data"));
592
593 auto args = opt.GetOptionVecString();
594 ASSERT_EQ(args.size(), 2);
595 ASSERT_EQ(args[0], "-o");
596 ASSERT_EQ(args[1], "perf.data");
597
598 opt.SetOption("-o", std::string(""));
599
600 args = opt.GetOptionVecString();
601 auto it = std::find(args.begin(), args.end(), "-o");
602 ASSERT_EQ(it, args.end());
603 }
604
605 /**
606 * @tc.desc: SetOption(const std::string &name, const std::vector<std::string> &vStr)
607 * @tc.type: FUNC
608 */
609 HWTEST_F(HiperfClientTest, RemoveExistingOptionWithEmptyVectorOfString, TestSize.Level2)
610 {
611 HiperfClient::RecordOption opt;
612 opt.SetOption("-e", std::vector<std::string>{"hw-cpu-cycles", "hw-instructions"});
613
614 auto args = opt.GetOptionVecString();
615 ASSERT_EQ(args.size(), 2);
616 ASSERT_EQ(args[0], "-e");
617 ASSERT_EQ(args[1], "hw-cpu-cycles,hw-instructions");
618
619 opt.SetOption("-e", std::vector<std::string>{});
620
621 args = opt.GetOptionVecString();
622 auto it = std::find(args.begin(), args.end(), "-e");
623 ASSERT_EQ(it, args.end());
624 }
625
626 /**
627 * @tc.desc: SetOption(const std::string &name, const std::vector<std::string> &vStr)
628 * @tc.type: FUNC
629 */
630 HWTEST_F(HiperfClientTest, UpdateExistingOptionWithVector, TestSize.Level2)
631 {
632 HiperfClient::RecordOption opt;
633 opt.SetOption("-e", std::vector<std::string>{"hw-cpu-cycles", "hw-instructions"});
634
635 auto args = opt.GetOptionVecString();
636 ASSERT_EQ(args.size(), 2);
637 ASSERT_EQ(args[0], "-e");
638 ASSERT_EQ(args[1], "hw-cpu-cycles,hw-instructions");
639
640 opt.SetOption("-e", std::vector<std::string>{"hw-cache-references", "hw-cache-misses"});
641
642 args = opt.GetOptionVecString();
643 ASSERT_EQ(args.size(), 2);
644 ASSERT_EQ(args[0], "-e");
645 ASSERT_EQ(args[1], "hw-cache-references,hw-cache-misses");
646 }
647 } // namespace HiPerf
648 } // namespace Developtools
649 } // namespace OHOS
650