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 #include "subcommand_stat_test.h"
16
17 #include <algorithm>
18 #include <cinttypes>
19 #include <regex>
20 #include <sstream>
21 #include <thread>
22
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 #include <hilog/log.h>
26 #include <sched.h>
27
28 #include "perf_events.h"
29 #include "tracked_command.h"
30
31 using namespace testing::ext;
32 using namespace std;
33 using namespace OHOS::HiviewDFX;
34 namespace OHOS {
35 namespace Developtools {
36 namespace HiPerf {
37 class SubCommandStatTest : public testing::Test {
38 public:
39 static void SetUpTestCase(void);
40 static void TearDownTestCase(void);
41 void SetUp();
42 void TearDown();
43
44 static void TestCodeThread(int &tid);
45 bool FindExpectStr(const std::string &stringOut, const std::string &counterNames) const;
46 uint EffectiveCounter(const std::string &stringOut,
47 const std::vector<std::string> &counterNames,
48 uint &effectiveHeadCounter) const;
49 uint EffectiveCounter(const std::string &stringOut, const std::string &counterNames,
50 uint &effectiveHeadCounter) const;
51 int CounterValue(const std::string &stringOut, const std::string &configName) const;
52 void CheckGroupCoverage(const std::string &stringOut,
53 const std::string &groupCounterName) const;
54
55 const std::vector<std::string> defaultConfigNames_ = {
56 "hw-branch-misses",
57 "hw-cpu-cycles",
58 "hw-instructions",
59 #if defined(__aarch64__)
60 "hw-stalled-cycles-backend",
61 "hw-stalled-cycles-frontend",
62 #endif
63 "sw-context-switches",
64 "sw-page-faults",
65 "sw-task-clock",
66 };
67
68 const int defaultRunTimeoutMs = 4100;
69 const std::string timeReportStr = "Report at ";
70 };
71
SetUpTestCase()72 void SubCommandStatTest::SetUpTestCase() {}
73
TearDownTestCase()74 void SubCommandStatTest::TearDownTestCase() {}
75
SetUp()76 void SubCommandStatTest::SetUp()
77 {
78 ASSERT_EQ(SubCommand::GetSubCommands().size(), 0u);
79 ASSERT_EQ(RegisterSubCommandStat(), true);
80 }
81
TearDown()82 void SubCommandStatTest::TearDown()
83 {
84 SubCommand::ClearSubCommands();
85 ASSERT_EQ(SubCommand::GetSubCommands().size(), 0u);
86 }
87
TestCodeThread(int & tid)88 void SubCommandStatTest::TestCodeThread(int &tid)
89 {
90 std::vector<std::unique_ptr<char[]>> mems;
91 tid = gettid();
92 printf("TestCodeThread:%d ++\n", tid);
93 constexpr int sleepTime {500};
94 const int sum = 10;
95 const int num = 2;
96 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
97
98 constexpr size_t memSize {1024};
99 for (uint i = 0; i < sum * memSize; i++) {
100 if (i % num == 0) {
101 mems.push_back(std::make_unique<char[]>(memSize));
102 } else {
103 mems.push_back(std::make_unique<char[]>(memSize * num));
104 }
105 }
106
107 for (uint i = 0; i < sum * memSize; i++) {
108 mems.pop_back();
109 }
110
111 std::this_thread::sleep_for(std::chrono::milliseconds(num * sleepTime));
112 printf("TestCodeThread:%d --\n", tid);
113 }
114
EffectiveCounter(const std::string & stringOut,const std::string & counterNames,uint & effectiveHeadCounter) const115 uint SubCommandStatTest::EffectiveCounter(const std::string &stringOut,
116 const std::string &counterNames,
117 uint &effectiveHeadCounter) const
118 {
119 std::string filterCounterNames {};
120 filterCounterNames = StringReplace(counterNames, ":u", "");
121 filterCounterNames = StringReplace(filterCounterNames, ":k", "");
122 return EffectiveCounter(stringOut, StringSplit(filterCounterNames, ","), effectiveHeadCounter);
123 }
124
FindExpectStr(const std::string & stringOut,const std::string & counterNames) const125 bool SubCommandStatTest::FindExpectStr(const std::string &stringOut,
126 const std::string &counterNames) const
127 {
128 auto lines = StringSplit(stringOut, "\n");
129 for (auto line : lines) {
130 if (line.find(counterNames.c_str()) != std::string::npos) {
131 return true;
132 }
133 }
134
135 return false;
136 }
137
EffectiveCounter(const std::string & stringOut,const std::vector<std::string> & counterNames,uint & effectiveHeadCounter) const138 uint SubCommandStatTest::EffectiveCounter(const std::string &stringOut,
139 const std::vector<std::string> &counterNames,
140 uint &effectiveHeadCounter) const
141 {
142 uint effectiveCounter = 0;
143 for (auto name : counterNames) {
144 EXPECT_NE(stringOut.find(name), std::string::npos);
145 }
146 auto lines = StringSplit(stringOut, "\n");
147 for (auto line : lines) {
148 if (line.find(timeReportStr.c_str()) != std::string::npos) {
149 printf("reset the count because found: '%s'\n", timeReportStr.c_str());
150 // reset the count
151 effectiveCounter = 0;
152 effectiveHeadCounter++;
153 continue;
154 }
155 auto tokens = StringSplit(line.c_str(), " ");
156 constexpr size_t sizeLimit {2};
157 std::regex pattern("^\\d+[,\\d{3}]*");
158 if (tokens.size() > sizeLimit &&
159 (IsDigits(tokens[0]) || std::regex_match(tokens[0], pattern))) {
160 if (find(counterNames.begin(), counterNames.end(), tokens[1]) != counterNames.end()) {
161 uint64_t count = std::stoull(tokens[0]);
162 effectiveCounter++;
163 printf("[%u] found %s:%s count %" PRIu64 "\n", effectiveCounter, tokens[1].c_str(),
164 tokens[0].c_str(), count);
165 }
166 }
167 }
168
169 // no more count than max
170 printf("effectiveCounter %u \n", effectiveCounter);
171 printf("effectiveHeadCounter %u \n", effectiveHeadCounter);
172
173 return effectiveCounter;
174 }
175
CounterValue(const std::string & stringOut,const std::string & configName) const176 int SubCommandStatTest::CounterValue(const std::string &stringOut,
177 const std::string &configName) const
178 {
179 int res {-1};
180 auto lines = StringSplit(stringOut, "\n");
181 for (auto line : lines) {
182 auto tokens = StringSplit(line.c_str(), " ");
183 constexpr size_t sizeLimit {2};
184 if (tokens.size() > sizeLimit and IsDigits(tokens[0])) {
185 if (tokens[1] == configName) {
186 uint64_t count = std::stoull(tokens[0]);
187 res += count;
188 }
189 }
190 }
191 if (res != -1) {
192 ++res;
193 }
194 return res;
195 }
196
CheckGroupCoverage(const std::string & stringOut,const std::string & groupCounterName) const197 void SubCommandStatTest::CheckGroupCoverage(const std::string &stringOut,
198 const std::string &groupCounterName) const
199 {
200 std::string filterGroupCounterName = StringReplace(groupCounterName, ":u", "");
201 filterGroupCounterName = StringReplace(filterGroupCounterName, ":k", "");
202 auto groupCounterNames = StringSplit(filterGroupCounterName, ",");
203
204 for (auto name : groupCounterNames) {
205 EXPECT_NE(stringOut.find(name), std::string::npos);
206 }
207 std::string groupCoverage;
208 auto lines = StringSplit(stringOut, "\n");
209 for (auto line : lines) {
210 auto tokens = StringSplit(line.c_str(), " ");
211 if (find(groupCounterNames.begin(), groupCounterNames.end(), tokens[1]) !=
212 groupCounterNames.end()) {
213 if (groupCoverage.empty()) {
214 groupCoverage = tokens.back();
215 } else {
216 EXPECT_EQ(groupCoverage, tokens.back());
217 }
218 }
219 }
220 }
221
222 /**
223 * @tc.name: TestOnSubCommand_a
224 * @tc.desc: -a
225 * @tc.type: FUNC
226 */
227 HWTEST_F(SubCommandStatTest, TestOnSubCommand_a, TestSize.Level1)
228 {
229 StdoutRecord stdoutRecord;
230 stdoutRecord.Start();
231 const auto startTime = chrono::steady_clock::now();
232 EXPECT_EQ(Command::DispatchCommand("stat -a -c 0 -d 3 --dumpoptions"), true);
233 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
234 chrono::steady_clock::now() - startTime);
235 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
236
237 std::string stringOut = stdoutRecord.Stop();
238 if (HasFailure()) {
239 printf("output:\n%s", stringOut.c_str());
240 }
241
242 // some times 'sw-page-faults' is 0
243 uint effectiveHeadCounter = 0;
244 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
245 (defaultConfigNames_.size() - 1));
246 }
247
248 /**
249 * @tc.name: TestOnSubCommand_a1
250 * @tc.desc: -a
251 * @tc.type: FUNC
252 */
253 HWTEST_F(SubCommandStatTest, TestOnSubCommand_a1, TestSize.Level1)
254 {
255 StdoutRecord stdoutRecord;
256 stdoutRecord.Start();
257 const auto startTime = chrono::steady_clock::now();
258 EXPECT_EQ(Command::DispatchCommand("stat -a -d 3 --dumpoptions"), true);
259 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
260 chrono::steady_clock::now() - startTime);
261 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
262
263 std::string stringOut = stdoutRecord.Stop();
264 printf("output:\n%s", stringOut.c_str());
265 if (HasFailure()) {
266 printf("output:\n%s", stringOut.c_str());
267 }
268
269 // some times 'sw-page-faults' is 0
270 uint effectiveHeadCounter = 0;
271 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
272 (defaultConfigNames_.size() - 1));
273 }
274
275 /**
276 * @tc.name: TestOnSubCommand_a2
277 * @tc.desc: -a
278 * @tc.type: FUNC
279 */
280 HWTEST_F(SubCommandStatTest, TestOnSubCommand_a2, TestSize.Level1)
281 {
282 StdoutRecord stdoutRecord;
283 stdoutRecord.Start();
284 const auto startTime = chrono::steady_clock::now();
285 EXPECT_EQ(Command::DispatchCommand("stat -a -d 3"), true);
286 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
287 chrono::steady_clock::now() - startTime);
288 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
289
290 std::string stringOut = stdoutRecord.Stop();
291 if (HasFailure()) {
292 printf("output:\n%s", stringOut.c_str());
293 }
294
295 // some times 'sw-page-faults' is 0
296 uint effectiveHeadCounter = 0;
297 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
298 (defaultConfigNames_.size() - 1));
299 }
300
301 /**
302 * @tc.name: TestOnSubCommand_a3
303 * @tc.desc: -a
304 * @tc.type: FUNC
305 */
306 HWTEST_F(SubCommandStatTest, TestOnSubCommand_a3, TestSize.Level1)
307 {
308 StdoutRecord stdoutRecord;
309 stdoutRecord.Start();
310 const auto startTime = chrono::steady_clock::now();
311 EXPECT_EQ(Command::DispatchCommand("stat -a -c 0 -d 3"), true);
312 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
313 chrono::steady_clock::now() - startTime);
314 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
315
316 std::string stringOut = stdoutRecord.Stop();
317 if (HasFailure()) {
318 printf("output:\n%s", stringOut.c_str());
319 }
320
321 // some times 'sw-page-faults' is 0
322 uint effectiveHeadCounter = 0;
323 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
324 (defaultConfigNames_.size() - 1));
325 }
326
327 /**
328 * @tc.name: TestOnSubCommand_a4
329 * @tc.desc: -a
330 * @tc.type: FUNC
331 */
332 HWTEST_F(SubCommandStatTest, TestOnSubCommand_a4, TestSize.Level1)
333 {
334 StdoutRecord stdoutRecord;
335 stdoutRecord.Start();
336 const auto startTime = chrono::steady_clock::now();
337 EXPECT_EQ(Command::DispatchCommand("stat -a test"), false);
338 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
339 chrono::steady_clock::now() - startTime);
340 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
341
342 std::string stringOut = stdoutRecord.Stop();
343 if (HasFailure()) {
344 printf("output:\n%s", stringOut.c_str());
345 }
346
347 // some times 'sw-page-faults' is 0
348 std::string expectStr = "failed";
349 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
350 }
351
352 /**
353 * @tc.name: TestOnSubCommand_c
354 * @tc.desc: -c
355 * @tc.type: FUNC
356 */
357 HWTEST_F(SubCommandStatTest, TestOnSubCommand_c, TestSize.Level1)
358 {
359 int tid1 = 0;
360 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
361
362 printf("wait child thread run.\n");
363 while (tid1 == 0) {
364 std::this_thread::sleep_for(std::chrono::milliseconds(10));
365 }
366 // we need bound us to cpu which we selelct
367 cpu_set_t mask, oldMask;
368 CPU_ZERO(&mask);
369 CPU_SET(1, &mask);
370
371 sched_getaffinity(0, sizeof(cpu_set_t), &oldMask);
372 sched_setaffinity(0, sizeof(cpu_set_t), &mask);
373 EXPECT_LE(CPU_COUNT(&mask), CPU_COUNT(&oldMask));
374
375 std::string cmdstr = "stat -p ";
376 cmdstr += std::to_string(tid1);
377 cmdstr += " -c 0 -d 3 --dumpoptions";
378
379 StdoutRecord stdoutRecord;
380 stdoutRecord.Start();
381 const auto startTime = chrono::steady_clock::now();
382 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
383 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
384 chrono::steady_clock::now() - startTime);
385 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
386
387 std::string stringOut = stdoutRecord.Stop();
388 if (HasFailure()) {
389 printf("output:\n%s", stringOut.c_str());
390 }
391 // some times 'sw-page-faults' is 0
392 uint effectiveHeadCounter = 0u;
393 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
394 (defaultConfigNames_.size() - 1));
395
396 EXPECT_NE(stringOut.find("Timeout exit"), std::string::npos);
397
398 sched_setaffinity(0, sizeof(cpu_set_t), &oldMask);
399 sched_getaffinity(0, sizeof(cpu_set_t), &mask);
400 EXPECT_EQ(CPU_COUNT(&mask), CPU_COUNT(&oldMask));
401 t1.join();
402 }
403
404 /**
405 * @tc.name: TestOnSubCommand_c1
406 * @tc.desc: -c
407 * @tc.type: FUNC
408 */
409 HWTEST_F(SubCommandStatTest, TestOnSubCommand_c1, TestSize.Level1)
410 {
411 int tid1 = 0;
412 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
413 while (tid1 == 0) {
414 std::this_thread::sleep_for(std::chrono::milliseconds(10));
415 }
416
417 std::string cmdstr = "stat -p ";
418 cmdstr += std::to_string(tid1);
419 cmdstr += " -c 1 -d 3";
420
421 StdoutRecord stdoutRecord;
422 stdoutRecord.Start();
423 const auto startTime = chrono::steady_clock::now();
424 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
425 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
426 chrono::steady_clock::now() - startTime);
427 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
428
429 std::string stringOut = stdoutRecord.Stop();
430 if (HasFailure()) {
431 printf("output:\n%s", stringOut.c_str());
432 }
433
434 // some times 'sw-page-faults' is 0
435 uint effectiveHeadCounter = 0;
436 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
437 (defaultConfigNames_.size() - 1));
438 t1.join();
439 }
440
441 /**
442 * @tc.name: TestOnSubCommand_c2
443 * @tc.desc: -c
444 * @tc.type: FUNC
445 */
446 HWTEST_F(SubCommandStatTest, TestOnSubCommand_c2, TestSize.Level1)
447 {
448 int tid1 = 0;
449 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
450 while (tid1 == 0) {
451 std::this_thread::sleep_for(std::chrono::milliseconds(10));
452 }
453
454 std::string cmdstr = "stat -p ";
455 cmdstr += std::to_string(tid1);
456 cmdstr += " -c 0,1 -d 3";
457
458 StdoutRecord stdoutRecord;
459 stdoutRecord.Start();
460 const auto startTime = chrono::steady_clock::now();
461 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
462 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
463 chrono::steady_clock::now() - startTime);
464 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
465
466 std::string stringOut = stdoutRecord.Stop();
467 if (HasFailure()) {
468 printf("output:\n%s", stringOut.c_str());
469 }
470
471 // some times 'sw-page-faults' is 0
472 uint effectiveHeadCounter = 0;
473 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
474 (defaultConfigNames_.size() - 1));
475 t1.join();
476 }
477
478 /**
479 * @tc.name: TestOnSubCommand_c3
480 * @tc.desc: -c
481 * @tc.type: FUNC
482 */
483 HWTEST_F(SubCommandStatTest, TestOnSubCommand_c3, TestSize.Level1)
484 {
485 StdoutRecord stdoutRecord;
486 stdoutRecord.Start();
487 const auto startTime = chrono::steady_clock::now();
488 EXPECT_EQ(Command::DispatchCommand("stat -a -c 0,1 -d 3"), true);
489 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
490 chrono::steady_clock::now() - startTime);
491 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
492
493 std::string stringOut = stdoutRecord.Stop();
494 if (HasFailure()) {
495 printf("output:\n%s", stringOut.c_str());
496 }
497
498 // some times 'sw-page-faults' is 0
499 uint effectiveHeadCounter = 0;
500 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
501 (defaultConfigNames_.size() - 1));
502 }
503
504 /**
505 * @tc.name: TestOnSubCommand_c4
506 * @tc.desc: -c
507 * @tc.type: FUNC
508 */
509 HWTEST_F(SubCommandStatTest, TestOnSubCommand_c4, TestSize.Level1)
510 {
511 int tid1 = 0;
512 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
513 while (tid1 == 0) {
514 std::this_thread::sleep_for(std::chrono::milliseconds(10));
515 }
516
517 std::string cmdstr = "stat -p ";
518 cmdstr += std::to_string(tid1);
519 cmdstr += " -c test -d 3";
520
521 StdoutRecord stdoutRecord;
522 stdoutRecord.Start();
523 const auto startTime = chrono::steady_clock::now();
524 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
525 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
526 chrono::steady_clock::now() - startTime);
527 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
528
529 std::string stringOut = stdoutRecord.Stop();
530 if (HasFailure()) {
531 printf("output:\n%s", stringOut.c_str());
532 }
533
534 // some times 'sw-page-faults' is 0
535 std::string expectStr = "incorrect option";
536 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
537 t1.join();
538 }
539
540 /**
541 * @tc.name: TestOnSubCommand_d
542 * @tc.desc: -d
543 * @tc.type: FUNC
544 */
545 HWTEST_F(SubCommandStatTest, TestOnSubCommand_d, TestSize.Level1)
546 {
547 int tid1 = 0;
548 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
549 while (tid1 == 0) {
550 std::this_thread::sleep_for(std::chrono::milliseconds(10));
551 }
552
553 std::string cmdstr = "stat -p ";
554 cmdstr += std::to_string(tid1);
555 cmdstr += " -c 0 -d 3 --dumpoptions";
556
557 StdoutRecord stdoutRecord;
558 stdoutRecord.Start();
559 const auto startTime = chrono::steady_clock::now();
560 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
561 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
562 chrono::steady_clock::now() - startTime);
563 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
564
565 std::string stringOut = stdoutRecord.Stop();
566 if (HasFailure()) {
567 printf("output:\n%s", stringOut.c_str());
568 }
569 // some times 'sw-page-faults' is 0
570 uint effectiveHeadCounter = 0u;
571 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
572 (defaultConfigNames_.size() - 1));
573 t1.join();
574 }
575
576 /**
577 * @tc.name: TestOnSubCommand_d1
578 * @tc.desc: -d
579 * @tc.type: FUNC
580 */
581 HWTEST_F(SubCommandStatTest, TestOnSubCommand_d1, TestSize.Level1)
582 {
583 StdoutRecord stdoutRecord;
584 stdoutRecord.Start();
585 const auto startTime = chrono::steady_clock::now();
586 EXPECT_EQ(Command::DispatchCommand("stat -a -d 3 --dumpoptions"), true);
587 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
588 chrono::steady_clock::now() - startTime);
589 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
590
591 std::string stringOut = stdoutRecord.Stop();
592 if (HasFailure()) {
593 printf("output:\n%s", stringOut.c_str());
594 }
595 // some times 'sw-page-faults' is 0
596 uint effectiveHeadCounter = 0u;
597 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
598 (defaultConfigNames_.size() - 1));
599 }
600
601 /**
602 * @tc.name: TestOnSubCommand_d2
603 * @tc.desc: -d
604 * @tc.type: FUNC
605 */
606 HWTEST_F(SubCommandStatTest, TestOnSubCommand_d2, TestSize.Level1)
607 {
608 int tid1 = 0;
609 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
610 while (tid1 == 0) {
611 std::this_thread::sleep_for(std::chrono::milliseconds(10));
612 }
613
614 std::string cmdstr = "stat -p ";
615 cmdstr += std::to_string(tid1);
616 cmdstr += " -d -1";
617
618 StdoutRecord stdoutRecord;
619 stdoutRecord.Start();
620 const auto startTime = chrono::steady_clock::now();
621 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
622 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
623 chrono::steady_clock::now() - startTime);
624 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
625
626 std::string stringOut = stdoutRecord.Stop();
627 if (HasFailure()) {
628 printf("output:\n%s", stringOut.c_str());
629 }
630 // some times 'sw-page-faults' is 0
631 std::string expectStr = "failed";
632 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
633 t1.join();
634 }
635
636 /**
637 * @tc.name: TestOnSubCommand_d3
638 * @tc.desc: -d
639 * @tc.type: FUNC
640 */
641 HWTEST_F(SubCommandStatTest, TestOnSubCommand_d3, TestSize.Level1)
642 {
643 int tid1 = 0;
644 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
645 while (tid1 == 0) {
646 std::this_thread::sleep_for(std::chrono::milliseconds(10));
647 }
648
649 std::string cmdstr = "stat -p ";
650 cmdstr += std::to_string(tid1);
651 cmdstr += " -d test";
652
653 StdoutRecord stdoutRecord;
654 stdoutRecord.Start();
655 const auto startTime = chrono::steady_clock::now();
656 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
657 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
658 chrono::steady_clock::now() - startTime);
659 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
660
661 std::string stringOut = stdoutRecord.Stop();
662 if (HasFailure()) {
663 printf("output:\n%s", stringOut.c_str());
664 }
665 // some times 'sw-page-faults' is 0
666 std::string expectStr = "incorrect option";
667 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
668 t1.join();
669 }
670
671 /**
672 * @tc.name: TestOnSubCommand_d4
673 * @tc.desc: -d
674 * @tc.type: FUNC
675 */
676 HWTEST_F(SubCommandStatTest, TestOnSubCommand_d4, TestSize.Level1)
677 {
678 int tid1 = 0;
679 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
680 while (tid1 == 0) {
681 std::this_thread::sleep_for(std::chrono::milliseconds(10));
682 }
683
684 std::string cmdstr = "stat -p ";
685 cmdstr += std::to_string(tid1);
686 cmdstr += " -c 0,1 -d 1";
687
688 StdoutRecord stdoutRecord;
689 stdoutRecord.Start();
690 const auto startTime = chrono::steady_clock::now();
691 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
692 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
693 chrono::steady_clock::now() - startTime);
694 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
695
696 std::string stringOut = stdoutRecord.Stop();
697 if (HasFailure()) {
698 printf("output:\n%s", stringOut.c_str());
699 }
700 // some times 'sw-page-faults' is 0
701 uint effectiveHeadCounter = 0u;
702 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
703 (defaultConfigNames_.size() - 1));
704 t1.join();
705 }
706
707 /**
708 * @tc.name: TestOnSubCommand_i
709 * @tc.desc: -i
710 * @tc.type: FUNC
711 */
712 HWTEST_F(SubCommandStatTest, TestOnSubCommand_i, TestSize.Level1)
713 {
714 int tid1 = 0;
715 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
716 while (tid1 == 0) {
717 std::this_thread::sleep_for(std::chrono::milliseconds(10));
718 }
719
720 std::string cmdstr = "stat -p ";
721 cmdstr += std::to_string(tid1);
722 cmdstr += " -c 0 -d 3 -i 1000 --dumpoptions";
723
724 StdoutRecord stdoutRecord;
725 stdoutRecord.Start();
726 const auto startTime = chrono::steady_clock::now();
727 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
728 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
729 chrono::steady_clock::now() - startTime);
730 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
731
732 std::string stringOut = stdoutRecord.Stop();
733 if (HasFailure()) {
734 printf("output:\n%s", stringOut.c_str());
735 }
736 // some times 'sw-page-faults' is 0
737 uint effectiveHeadCounter = 0u;
738 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
739 (defaultConfigNames_.size() - 1));
740
741 EXPECT_GE(effectiveHeadCounter, 3u);
742 t1.join();
743 }
744
745 /**
746 * @tc.name: TestOnSubCommand_i1
747 * @tc.desc: -i
748 * @tc.type: FUNC
749 */
750 HWTEST_F(SubCommandStatTest, TestOnSubCommand_i1, TestSize.Level1)
751 {
752 int tid1 = 0;
753 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
754 while (tid1 == 0) {
755 std::this_thread::sleep_for(std::chrono::milliseconds(10));
756 }
757
758 std::string cmdstr = "stat -p ";
759 cmdstr += std::to_string(tid1);
760 cmdstr += " -c 0 -d 3 -i 500 --dumpoptions";
761
762 StdoutRecord stdoutRecord;
763 stdoutRecord.Start();
764 const auto startTime = chrono::steady_clock::now();
765 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
766 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
767 chrono::steady_clock::now() - startTime);
768 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
769
770 std::string stringOut = stdoutRecord.Stop();
771 if (HasFailure()) {
772 printf("output:\n%s", stringOut.c_str());
773 }
774 // some times 'sw-page-faults' is 0
775 uint effectiveHeadCounter = 0u;
776 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
777 (defaultConfigNames_.size() - 1));
778
779 EXPECT_GE(effectiveHeadCounter, 3u);
780 t1.join();
781 }
782
783 /**
784 * @tc.name: TestOnSubCommand_i2
785 * @tc.desc: -i
786 * @tc.type: FUNC
787 */
788 HWTEST_F(SubCommandStatTest, TestOnSubCommand_i2, TestSize.Level1)
789 {
790 int tid1 = 0;
791 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
792 while (tid1 == 0) {
793 std::this_thread::sleep_for(std::chrono::milliseconds(10));
794 }
795
796 std::string cmdstr = "stat -p ";
797 cmdstr += std::to_string(tid1);
798 cmdstr += " -c 0 -d 3 -i -1 --dumpoptions";
799
800 StdoutRecord stdoutRecord;
801 stdoutRecord.Start();
802 const auto startTime = chrono::steady_clock::now();
803 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
804 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
805 chrono::steady_clock::now() - startTime);
806 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
807
808 std::string stringOut = stdoutRecord.Stop();
809 if (HasFailure()) {
810 printf("output:\n%s", stringOut.c_str());
811 }
812 // some times 'sw-page-faults' is 0
813 std::string expectStr = "failed";
814 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
815 t1.join();
816 }
817
818 /**
819 * @tc.name: TestOnSubCommand_i2
820 * @tc.desc: -i
821 * @tc.type: FUNC
822 */
823 HWTEST_F(SubCommandStatTest, TestOnSubCommand_i3, TestSize.Level1)
824 {
825 int tid1 = 0;
826 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
827 while (tid1 == 0) {
828 std::this_thread::sleep_for(std::chrono::milliseconds(10));
829 }
830
831 std::string cmdstr = "stat -p ";
832 cmdstr += std::to_string(tid1);
833 cmdstr += " -c 0 -d 3 -i test --dumpoptions";
834
835 StdoutRecord stdoutRecord;
836 stdoutRecord.Start();
837 const auto startTime = chrono::steady_clock::now();
838 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
839 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
840 chrono::steady_clock::now() - startTime);
841 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
842
843 std::string stringOut = stdoutRecord.Stop();
844 if (HasFailure()) {
845 printf("output:\n%s", stringOut.c_str());
846 }
847 // some times 'sw-page-faults' is 0
848 std::string expectStr = "incorrect";
849 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
850 t1.join();
851 }
852
853 /**
854 * @tc.name: TestOnSubCommand_i4
855 * @tc.desc: -i
856 * @tc.type: FUNC
857 */
858 HWTEST_F(SubCommandStatTest, TestOnSubCommand_i4, TestSize.Level1)
859 {
860 int tid1 = 0;
861 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
862 while (tid1 == 0) {
863 std::this_thread::sleep_for(std::chrono::milliseconds(10));
864 }
865
866 std::string cmdstr = "stat -p ";
867 cmdstr += std::to_string(tid1);
868 cmdstr += " -c 0 -d 1 -i 100 --dumpoptions";
869
870 StdoutRecord stdoutRecord;
871 stdoutRecord.Start();
872 const auto startTime = chrono::steady_clock::now();
873 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
874 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
875 chrono::steady_clock::now() - startTime);
876 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
877
878 std::string stringOut = stdoutRecord.Stop();
879 if (HasFailure()) {
880 printf("output:\n%s", stringOut.c_str());
881 }
882 // some times 'sw-page-faults' is 0
883 uint effectiveHeadCounter = 0u;
884 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
885 (defaultConfigNames_.size() - 1));
886
887 EXPECT_GE(effectiveHeadCounter, 3u);
888 t1.join();
889 }
890
891 /**
892 * @tc.name: TestOnSubCommand_e
893 * @tc.desc: -e261
894 * @tc.type: FUNC
895 */
896 HWTEST_F(SubCommandStatTest, TestOnSubCommand_e, TestSize.Level1)
897 {
898 int tid1 = 0;
899 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
900 while (tid1 == 0) {
901 std::this_thread::sleep_for(std::chrono::milliseconds(10));
902 }
903
904 std::string cmdstr = "stat -p ";
905 cmdstr += std::to_string(tid1);
906 cmdstr += " -e hw-instructions -c 0 -d 3 --dumpoptions";
907
908 StdoutRecord stdoutRecord;
909 stdoutRecord.Start();
910 const auto startTime = chrono::steady_clock::now();
911 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
912 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
913 chrono::steady_clock::now() - startTime);
914 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
915
916 std::string stringOut = stdoutRecord.Stop();
917 if (HasFailure()) {
918 printf("output:\n%s", stringOut.c_str());
919 }
920 const std::vector<std::string> configNmaes = {"hw-instructions"};
921 uint effectiveHeadCounter = 0u;
922 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
923 t1.join();
924 }
925
926 /**
927 * @tc.name: TestOnSubCommand_e1
928 * @tc.desc: -e261
929 * @tc.type: FUNC
930 */
931 HWTEST_F(SubCommandStatTest, TestOnSubCommand_e1, TestSize.Level1)
932 {
933 int tid1 = 0;
934 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
935 while (tid1 == 0) {
936 std::this_thread::sleep_for(std::chrono::milliseconds(10));
937 }
938
939 std::string cmdstr = "stat -p ";
940 cmdstr += std::to_string(tid1);
941 cmdstr += " -e hw-branch-misses -c 0 -d 3 --dumpoptions";
942
943 StdoutRecord stdoutRecord;
944 stdoutRecord.Start();
945 const auto startTime = chrono::steady_clock::now();
946 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
947 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
948 chrono::steady_clock::now() - startTime);
949 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
950
951 std::string stringOut = stdoutRecord.Stop();
952 if (HasFailure()) {
953 printf("output:\n%s", stringOut.c_str());
954 }
955 const std::vector<std::string> configNmaes = {"hw-branch-misses"};
956 uint effectiveHeadCounter = 0u;
957 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
958 t1.join();
959 }
960
961 /**
962 * @tc.name: TestOnSubCommand_e2
963 * @tc.desc: -e261
964 * @tc.type: FUNC
965 */
966 HWTEST_F(SubCommandStatTest, TestOnSubCommand_e2, TestSize.Level1)
967 {
968 int tid1 = 0;
969 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
970 while (tid1 == 0) {
971 std::this_thread::sleep_for(std::chrono::milliseconds(10));
972 }
973
974 std::string cmdstr = "stat -p ";
975 cmdstr += std::to_string(tid1);
976 cmdstr += " -e hw-cpu-cycles -c 0 -d 3 --dumpoptions";
977
978 StdoutRecord stdoutRecord;
979 stdoutRecord.Start();
980 const auto startTime = chrono::steady_clock::now();
981 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
982 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
983 chrono::steady_clock::now() - startTime);
984 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
985
986 std::string stringOut = stdoutRecord.Stop();
987 if (HasFailure()) {
988 printf("output:\n%s", stringOut.c_str());
989 }
990 const std::vector<std::string> configNmaes = {"hw-cpu-cycles"};
991 uint effectiveHeadCounter = 0u;
992 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
993 t1.join();
994 }
995
996 /**
997 * @tc.name: TestOnSubCommand_e3
998 * @tc.desc: -e261
999 * @tc.type: FUNC
1000 */
1001 HWTEST_F(SubCommandStatTest, TestOnSubCommand_e3, TestSize.Level1)
1002 {
1003 int tid1 = 0;
1004 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1005 while (tid1 == 0) {
1006 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1007 }
1008
1009 std::string cmdstr = "stat -p ";
1010 cmdstr += std::to_string(tid1);
1011 cmdstr += " -e hw-instructions -c 0 -d 3 --dumpoptions";
1012
1013 StdoutRecord stdoutRecord;
1014 stdoutRecord.Start();
1015 const auto startTime = chrono::steady_clock::now();
1016 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1017 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1018 chrono::steady_clock::now() - startTime);
1019 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1020
1021 std::string stringOut = stdoutRecord.Stop();
1022 if (HasFailure()) {
1023 printf("output:\n%s", stringOut.c_str());
1024 }
1025 const std::vector<std::string> configNmaes = {"hw-instructions"};
1026 uint effectiveHeadCounter = 0u;
1027 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1028 t1.join();
1029 }
1030
1031 /**
1032 * @tc.name: TestOnSubCommand_e4
1033 * @tc.desc: -e261
1034 * @tc.type: FUNC
1035 */
1036 HWTEST_F(SubCommandStatTest, TestOnSubCommand_e4, TestSize.Level1)
1037 {
1038 int tid1 = 0;
1039 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1040 while (tid1 == 0) {
1041 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1042 }
1043
1044 std::string cmdstr = "stat -p ";
1045 cmdstr += std::to_string(tid1);
1046 cmdstr += " -e hw-branch-test -c 0 -d 3 --dumpoptions";
1047
1048 StdoutRecord stdoutRecord;
1049 stdoutRecord.Start();
1050 const auto startTime = chrono::steady_clock::now();
1051 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
1052 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1053 chrono::steady_clock::now() - startTime);
1054 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1055
1056 std::string stringOut = stdoutRecord.Stop();
1057 if (HasFailure()) {
1058 printf("output:\n%s", stringOut.c_str());
1059 }
1060 std::string expectStr = "event is not supported";
1061 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1062 t1.join();
1063 }
1064
1065 /**
1066 * @tc.name: TestOnSubCommand_g
1067 * @tc.desc: -g
1068 * @tc.type: FUNC
1069 */
1070 HWTEST_F(SubCommandStatTest, TestOnSubCommand_g, TestSize.Level1)
1071 {
1072 int tid1 = 0;
1073 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1074 while (tid1 == 0) {
1075 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1076 }
1077
1078 std::string cmdstr = "stat -p ";
1079 cmdstr += std::to_string(tid1);
1080 cmdstr += " -g hw-branch-misses"
1081 " -g hw-cpu-cycles,hw-instructions"
1082 " -c 0 -d 3 --dumpoptions";
1083
1084 StdoutRecord stdoutRecord;
1085 stdoutRecord.Start();
1086 const auto startTime = chrono::steady_clock::now();
1087 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1088 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1089 chrono::steady_clock::now() - startTime);
1090 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1091
1092 const std::string stringOut = stdoutRecord.Stop();
1093 if (HasFailure()) {
1094 printf("output:\n%s", stringOut.c_str());
1095 }
1096
1097 const std::vector<std::string> configNmaes = {
1098 "hw-branch-misses",
1099 "hw-cpu-cycles",
1100 "hw-instructions",
1101 };
1102 uint effectiveHeadCounter = 0u;
1103 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1104 t1.join();
1105 }
1106
1107 /**
1108 * @tc.name: TestOnSubCommand_g1
1109 * @tc.desc: -g
1110 * @tc.type: FUNC
1111 */
1112 HWTEST_F(SubCommandStatTest, TestOnSubCommand_g1, TestSize.Level1)
1113 {
1114 int tid1 = 0;
1115 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1116 while (tid1 == 0) {
1117 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1118 }
1119
1120 std::string cmdstr = "stat -p ";
1121 cmdstr += std::to_string(tid1);
1122 cmdstr += " -g hw-instructions,hw-branch-misses"
1123 " -c 0 -d 3 --dumpoptions";
1124
1125 StdoutRecord stdoutRecord;
1126 stdoutRecord.Start();
1127 const auto startTime = chrono::steady_clock::now();
1128 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1129 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1130 chrono::steady_clock::now() - startTime);
1131 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1132
1133 const std::string stringOut = stdoutRecord.Stop();
1134 if (HasFailure()) {
1135 printf("output:\n%s", stringOut.c_str());
1136 }
1137
1138 const std::vector<std::string> configNmaes = {
1139 "hw-instructions",
1140 "hw-branch-misses",
1141 };
1142 uint effectiveHeadCounter = 0u;
1143 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1144 t1.join();
1145 }
1146
1147 /**
1148 * @tc.name: TestOnSubCommand_g2
1149 * @tc.desc: -g
1150 * @tc.type: FUNC
1151 */
1152 HWTEST_F(SubCommandStatTest, TestOnSubCommand_g2, TestSize.Level1)
1153 {
1154 int tid1 = 0;
1155 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1156 while (tid1 == 0) {
1157 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1158 }
1159
1160 std::string cmdstr = "stat -p ";
1161 cmdstr += std::to_string(tid1);
1162 cmdstr += " -g hw-cpu-cycles,hw-instructions"
1163 " -c 0 -d 3 --dumpoptions";
1164
1165 StdoutRecord stdoutRecord;
1166 stdoutRecord.Start();
1167 const auto startTime = chrono::steady_clock::now();
1168 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1169 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1170 chrono::steady_clock::now() - startTime);
1171 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1172
1173 const std::string stringOut = stdoutRecord.Stop();
1174 if (HasFailure()) {
1175 printf("output:\n%s", stringOut.c_str());
1176 }
1177
1178 const std::vector<std::string> configNmaes = {
1179 "hw-cpu-cycles",
1180 "hw-instructions",
1181 };
1182 uint effectiveHeadCounter = 0u;
1183 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1184 t1.join();
1185 }
1186
1187 /**
1188 * @tc.name: TestOnSubCommand_g3
1189 * @tc.desc: -g
1190 * @tc.type: FUNC
1191 */
1192 HWTEST_F(SubCommandStatTest, TestOnSubCommand_g3, TestSize.Level1)
1193 {
1194 int tid1 = 0;
1195 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1196 while (tid1 == 0) {
1197 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1198 }
1199
1200 std::string cmdstr = "stat -p ";
1201 cmdstr += std::to_string(tid1);
1202 cmdstr += " -g hw-cpu-test,hw-instructions"
1203 " -c 0 -d 3 --dumpoptions";
1204
1205 StdoutRecord stdoutRecord;
1206 stdoutRecord.Start();
1207 const auto startTime = chrono::steady_clock::now();
1208 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
1209 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1210 chrono::steady_clock::now() - startTime);
1211 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1212
1213 const std::string stringOut = stdoutRecord.Stop();
1214 if (HasFailure()) {
1215 printf("output:\n%s", stringOut.c_str());
1216 }
1217
1218 std::string expectStr = "event is not supported";
1219 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1220 t1.join();
1221 }
1222
1223 /**
1224 * @tc.name: TestOnSubCommand_g_uk
1225 * @tc.desc: -g u:k
1226 * @tc.type: FUNC
1227 */
1228 HWTEST_F(SubCommandStatTest, TestOnSubCommand_g_uk, TestSize.Level1)
1229 {
1230 int tid1 = 0;
1231 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1232 while (tid1 == 0) {
1233 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1234 }
1235
1236 std::string cmdstr = "stat -p ";
1237 cmdstr += std::to_string(tid1);
1238 cmdstr += " -g hw-branch-misses:k"
1239 " -g hw-cpu-cycles:k,hw-instructions:k"
1240 " -c 0 -d 3 --dumpoptions";
1241
1242 StdoutRecord stdoutRecord;
1243 stdoutRecord.Start();
1244 const auto startTime = chrono::steady_clock::now();
1245 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1246 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1247 chrono::steady_clock::now() - startTime);
1248 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1249
1250 std::string stringOut = stdoutRecord.Stop();
1251 if (HasFailure()) {
1252 printf("output:\n%s", stringOut.c_str());
1253 }
1254 const std::vector<std::string> configNmaes = {
1255 "hw-branch-misses:k",
1256 "hw-cpu-cycles:k",
1257 "hw-instructions:k",
1258 };
1259 // some times 'sw-page-faults' is 0
1260 uint effectiveHeadCounter = 0u;
1261 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1262 CheckGroupCoverage(stringOut, "hw-branch-misses:k");
1263 CheckGroupCoverage(stringOut, "hw-cpu-cycles:k,hw-instructions:k");
1264 t1.join();
1265 }
1266
1267 /**
1268 * @tc.name: TestOnSubCommand_p_t
1269 * @tc.desc: -p -t
1270 * @tc.type: FUNC
1271 */
1272 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p_t, TestSize.Level1)
1273 {
1274 int tid1 = 0;
1275 int tid2 = 0;
1276 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1277 std::thread t2(SubCommandStatTest::TestCodeThread, std::ref(tid2));
1278
1279 printf("wait child thread run.\n");
1280 while (tid1 * tid2 == 0) {
1281 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1282 }
1283
1284 StdoutRecord stdoutRecord;
1285 stdoutRecord.Start();
1286 const auto startTime = chrono::steady_clock::now();
1287
1288 std::string tidString = " -t ";
1289 tidString += std::to_string(tid1) + ",";
1290 tidString += std::to_string(tid2);
1291
1292 std::string cmdString = "stat";
1293 cmdString += tidString;
1294 cmdString += " -c 0 -d 3 --dumpoptions";
1295
1296 EXPECT_EQ(Command::DispatchCommand(cmdString), true);
1297 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1298 chrono::steady_clock::now() - startTime);
1299 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1300
1301 std::string stringOut = stdoutRecord.Stop();
1302 if (HasFailure()) {
1303 printf("output:\n%s", stringOut.c_str());
1304 }
1305 // some times 'sw-page-faults' is 0
1306 uint effectiveHeadCounter = 0u;
1307 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
1308 (defaultConfigNames_.size() - 1));
1309
1310 t1.join();
1311 t2.join();
1312 }
1313
1314 /**
1315 * @tc.name: TestOnSubCommand_p_t1
1316 * @tc.desc: -p -t
1317 * @tc.type: FUNC
1318 */
1319 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p_t1, TestSize.Level1)
1320 {
1321 int tid1 = 0;
1322 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1323 while (tid1 == 0) {
1324 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1325 }
1326
1327 StdoutRecord stdoutRecord;
1328 stdoutRecord.Start();
1329 const auto startTime = chrono::steady_clock::now();
1330
1331 std::string tidString = " -t ";
1332 tidString += std::to_string(tid1);
1333
1334 std::string cmdString = "stat";
1335 cmdString += tidString;
1336 cmdString += " -c 0 -d 3 --dumpoptions";
1337
1338 EXPECT_EQ(Command::DispatchCommand(cmdString), true);
1339 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1340 chrono::steady_clock::now() - startTime);
1341 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1342
1343 std::string stringOut = stdoutRecord.Stop();
1344 if (HasFailure()) {
1345 printf("output:\n%s", stringOut.c_str());
1346 }
1347 // some times 'sw-page-faults' is 0
1348 uint effectiveHeadCounter = 0u;
1349 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
1350 (defaultConfigNames_.size() - 1));
1351 t1.join();
1352 }
1353
1354 /**
1355 * @tc.name: TestOnSubCommand_p_t2
1356 * @tc.desc: -p -t
1357 * @tc.type: FUNC
1358 */
1359 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p_t2, TestSize.Level1)
1360 {
1361 StdoutRecord stdoutRecord;
1362 stdoutRecord.Start();
1363 const auto startTime = chrono::steady_clock::now();
1364
1365 std::string tidString = " -t ";
1366 tidString += "-1";
1367
1368 std::string cmdString = "stat";
1369 cmdString += tidString;
1370 cmdString += " -c 0 -d 3 --dumpoptions";
1371
1372 EXPECT_EQ(Command::DispatchCommand(cmdString), false);
1373 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1374 chrono::steady_clock::now() - startTime);
1375 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1376
1377 std::string stringOut = stdoutRecord.Stop();
1378 if (HasFailure()) {
1379 printf("output:\n%s", stringOut.c_str());
1380 }
1381
1382 std::string expectStr = "failed";
1383 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1384 }
1385
1386 /**
1387 * @tc.name: TestOnSubCommand_p_t3
1388 * @tc.desc: -p -t
1389 * @tc.type: FUNC
1390 */
1391 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p_t3, TestSize.Level1)
1392 {
1393 StdoutRecord stdoutRecord;
1394 stdoutRecord.Start();
1395 const auto startTime = chrono::steady_clock::now();
1396
1397 std::string tidString = " -t ";
1398 tidString += "test";
1399
1400 std::string cmdString = "stat";
1401 cmdString += tidString;
1402 cmdString += " -c 0 -d 3 --dumpoptions";
1403
1404 EXPECT_EQ(Command::DispatchCommand(cmdString), false);
1405 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1406 chrono::steady_clock::now() - startTime);
1407 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1408
1409 std::string stringOut = stdoutRecord.Stop();
1410 if (HasFailure()) {
1411 printf("output:\n%s", stringOut.c_str());
1412 }
1413
1414 std::string expectStr = "incorrect";
1415 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1416 }
1417
1418 /**
1419 * @tc.name: TestOnSubCommand_p_t4
1420 * @tc.desc: -p -t
1421 * @tc.type: FUNC
1422 */
1423 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p_t4, TestSize.Level1)
1424 {
1425 int tid1 = 0;
1426 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1427
1428 printf("wait child thread run.\n");
1429 while (tid1 == 0) {
1430 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1431 }
1432
1433 StdoutRecord stdoutRecord;
1434 stdoutRecord.Start();
1435 const auto startTime = chrono::steady_clock::now();
1436
1437 std::string tidString = " -t ";
1438 tidString += std::to_string(tid1);
1439
1440 std::string cmdString = "stat";
1441 cmdString += tidString;
1442 cmdString += " -c 0 -d 3 --dumpoptions";
1443
1444 EXPECT_EQ(Command::DispatchCommand(cmdString), true);
1445 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1446 chrono::steady_clock::now() - startTime);
1447 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1448
1449 std::string stringOut = stdoutRecord.Stop();
1450 if (HasFailure()) {
1451 printf("output:\n%s", stringOut.c_str());
1452 }
1453 // some times 'sw-page-faults' is 0
1454 uint effectiveHeadCounter = 0u;
1455 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
1456 (defaultConfigNames_.size() - 1));
1457 t1.join();
1458 }
1459
1460 /**
1461 * @tc.name: TestOnSubCommand_verbose
1462 * @tc.desc: -p -t
1463 * @tc.type: FUNC
1464 */
1465 HWTEST_F(SubCommandStatTest, TestOnSubCommand_verbose, TestSize.Level1)
1466 {
1467 int tid1 = 0;
1468 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1469
1470 printf("wait child thread run.\n");
1471 while (tid1 == 0) {
1472 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1473 }
1474
1475 StdoutRecord stdoutRecord;
1476 stdoutRecord.Start();
1477 const auto startTime = chrono::steady_clock::now();
1478
1479 std::string tidString = " -t ";
1480 tidString += std::to_string(tid1);
1481
1482 std::string cmdString = "stat";
1483 cmdString += tidString;
1484 cmdString += " -c 0 -d 3 --verbose";
1485
1486 EXPECT_EQ(Command::DispatchCommand(cmdString), true);
1487 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1488 chrono::steady_clock::now() - startTime);
1489 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1490
1491 std::string stringOut = stdoutRecord.Stop();
1492 if (HasFailure()) {
1493 printf("output:\n%s", stringOut.c_str());
1494 }
1495
1496 std::string expectStr = "time_enabled:";
1497 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1498 t1.join();
1499 }
1500
1501 /**
1502 * @tc.name: TestOnSubCommand_verbose1
1503 * @tc.desc: -p -t
1504 * @tc.type: FUNC
1505 */
1506 HWTEST_F(SubCommandStatTest, TestOnSubCommand_verbose1, TestSize.Level1)
1507 {
1508 int tid1 = 0;
1509 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1510
1511 printf("wait child thread run.\n");
1512 while (tid1 == 0) {
1513 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1514 }
1515
1516 StdoutRecord stdoutRecord;
1517 stdoutRecord.Start();
1518 const auto startTime = chrono::steady_clock::now();
1519
1520 std::string tidString = " -t ";
1521 tidString += std::to_string(tid1);
1522
1523 std::string cmdString = "stat";
1524 cmdString += tidString;
1525 cmdString += " -c 0 -d 3";
1526
1527 EXPECT_EQ(Command::DispatchCommand(cmdString), true);
1528 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1529 chrono::steady_clock::now() - startTime);
1530 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1531
1532 std::string stringOut = stdoutRecord.Stop();
1533 if (HasFailure()) {
1534 printf("output:\n%s", stringOut.c_str());
1535 }
1536
1537 std::string expectStr = "time_enabled:";
1538 EXPECT_EQ(FindExpectStr(stringOut, expectStr), false);
1539 t1.join();
1540 }
1541
1542 /**
1543 * @tc.name: TestOnSubCommand_cmd
1544 * @tc.desc: hiperf stat <cmd>
1545 * @tc.type: FUNC
1546 */
1547 HWTEST_F(SubCommandStatTest, TestOnSubCommand_cmd, TestSize.Level1)
1548 {
1549 std::string cmdstr = "stat -c 0 -d 3 --dumpoptions ls -l";
1550
1551 StdoutRecord stdoutRecord;
1552 stdoutRecord.Start();
1553 const auto startTime = chrono::steady_clock::now();
1554 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1555 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1556 chrono::steady_clock::now() - startTime);
1557 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1558
1559 std::string stringOut = stdoutRecord.Stop();
1560 if (HasFailure()) {
1561 printf("output:\n%s", stringOut.c_str());
1562 }
1563 // some times 'sw-page-faults' is 0
1564 uint effectiveHeadCounter = 0u;
1565 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
1566 (defaultConfigNames_.size() - 1));
1567 }
1568
1569 /**
1570 * @tc.name: TestOnSubCommand_ni
1571 * @tc.desc: --no-inherit
1572 * @tc.type: FUNC
1573 */
1574 HWTEST_F(SubCommandStatTest, TestOnSubCommand_ni, TestSize.Level1)
1575 {
1576 StdoutRecord stdoutRecord;
1577 const std::string configName {"sw-cpu-clock"};
1578 const std::string cmdPath {" ls"};
1579
1580 stdoutRecord.Start();
1581 std::string testCMD = "stat --no-inherit -c 0 -d 3 --dumpoptions -e ";
1582 testCMD += configName;
1583 testCMD += cmdPath;
1584 const auto tick2 = std::chrono::steady_clock::now();
1585 EXPECT_EQ(Command::DispatchCommand(testCMD), true);
1586 const auto tock2 = std::chrono::steady_clock::now();
1587 const auto costMs2 = std::chrono::duration_cast<std::chrono::milliseconds>(tock2 - tick2);
1588 EXPECT_LE(costMs2.count(), defaultRunTimeoutMs);
1589 std::string stringOut = stdoutRecord.Stop();
1590 if (HasFailure()) {
1591 printf("output:\n%s", stringOut.c_str());
1592 }
1593 int counterValueWithoutInherit = CounterValue(stringOut, configName);
1594 EXPECT_NE(counterValueWithoutInherit, 0);
1595 HLOGD("%s %d", configName.c_str(), counterValueWithoutInherit);
1596 }
1597
1598 // ParseOption DumpOptions PrintUsage
1599 /**
1600 * @tc.name: TestParseOption_ni
1601 * @tc.desc: --no-inherit
1602 * @tc.type: FUNC
1603 */
1604 HWTEST_F(SubCommandStatTest, TestParseOption, TestSize.Level1)
1605 {
1606 SubCommandStat cmdStat;
1607 std::vector<std::string> args;
1608 args = {"-h"};
1609 EXPECT_EQ(cmdStat.ParseOption(args), true);
1610 args = {"-a"};
1611 EXPECT_EQ(cmdStat.ParseOption(args), true);
1612 args = {"-c"};
1613 EXPECT_EQ(cmdStat.ParseOption(args), false);
1614 args = {"-d"};
1615 EXPECT_EQ(cmdStat.ParseOption(args), false);
1616 args = {"-i"};
1617 EXPECT_EQ(cmdStat.ParseOption(args), false);
1618 args = {"-e"};
1619 EXPECT_EQ(cmdStat.ParseOption(args), false);
1620 args = {"-g"};
1621 EXPECT_EQ(cmdStat.ParseOption(args), false);
1622 args = {"--no-inherit"};
1623 EXPECT_EQ(cmdStat.ParseOption(args), true);
1624 args = {"-p"};
1625 EXPECT_EQ(cmdStat.ParseOption(args), false);
1626 args = {"-t"};
1627 EXPECT_EQ(cmdStat.ParseOption(args), false);
1628 args = {"--verbose"};
1629 EXPECT_EQ(cmdStat.ParseOption(args), true);
1630 args.clear();
1631 EXPECT_EQ(cmdStat.ParseOption(args), true);
1632 }
1633
1634 /**
1635 * @tc.name: TestDumpOptions
1636 * @tc.desc:
1637 * @tc.type: FUNC
1638 */
1639 HWTEST_F(SubCommandStatTest, TestDumpOptions, TestSize.Level1)
1640 {
1641 SubCommandStat cmdStat;
1642 cmdStat.DumpOptions();
1643 EXPECT_EQ(1, 1);
1644 }
1645
1646 /**
1647 * @tc.name: TestPrintUsage
1648 * @tc.desc:
1649 * @tc.type: FUNC
1650 */
1651 HWTEST_F(SubCommandStatTest, TestPrintUsage, TestSize.Level1)
1652 {
1653 SubCommandStat cmdStat;
1654 cmdStat.PrintUsage();
1655 EXPECT_EQ(1, 1);
1656 }
1657
1658 /**
1659 * @tc.name: TestCheckOptions
1660 * @tc.desc:
1661 * @tc.type: FUNC
1662 */
1663 HWTEST_F(SubCommandStatTest, TestCheckOptions, TestSize.Level1)
1664 {
1665 SubCommandStat cmdStat;
1666 std::vector<pid_t> pids;
1667
1668 cmdStat.timeStopSec_ = -1;
1669 EXPECT_EQ(cmdStat.CheckOptions(pids), false);
1670
1671 cmdStat.timeReportMs_ = -1;
1672 EXPECT_EQ(cmdStat.CheckOptions(pids), false);
1673
1674 cmdStat.targetSystemWide_ = true;
1675 pids = {1112, 1113};
1676 EXPECT_EQ(cmdStat.CheckOptions(pids), false);
1677
1678 cmdStat.trackedCommand_ = {"test"};
1679 EXPECT_EQ(cmdStat.CheckOptions(pids), false);
1680
1681 cmdStat.targetSystemWide_ = false;
1682 EXPECT_EQ(cmdStat.CheckOptions(pids), false);
1683 }
1684
1685 /**
1686 * @tc.name: TestReport
1687 * @tc.desc:
1688 * @tc.type: FUNC
1689 */
1690 HWTEST_F(SubCommandStatTest, TestReport, TestSize.Level1)
1691 {
1692 SubCommandStat cmdStat;
1693 std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> countEvents;
1694 std::unique_ptr<PerfEvents::CountEvent> testEvent(std::make_unique<PerfEvents::CountEvent>());
1695 std::string test = "test";
1696 countEvents[test] = std::move(testEvent);
1697 cmdStat.Report(countEvents);
1698 EXPECT_EQ(1, 1);
1699 }
1700
1701 /**
1702 * @tc.name: TestReport_Piling
1703 * @tc.desc:
1704 * @tc.type: FUNC
1705 */
1706 HWTEST_F(SubCommandStatTest, TestReport_Piling, TestSize.Level1)
1707 {
1708 SubCommandStat cmdStat;
1709 std::vector<std::string> eventNames = {
1710 "hw-branch-instructions", "hw-branch-misses", "hw-cpu-cycles", "hw-instructions",
1711 "sw-context-switches", "sw-page-faults", "sw-task-clock", "sw-cpu-migrations"};
1712 StdoutRecord stdoutRecord;
1713 stdoutRecord.Start();
1714 std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> countEvents;
1715 for (int i = 0; i < 8; i++) {
1716 auto countEvent = make_unique<PerfEvents::CountEvent>(PerfEvents::CountEvent {});
1717 std::string configName = eventNames[i];
1718 countEvents[configName] = std::move(countEvent);
1719 countEvents[configName]->userOnly = false;
1720 countEvents[configName]->kernelOnly = false;
1721 std::unique_ptr<PerfEvents::CountEvent> &countEventTmp = countEvents[configName];
1722 if (i == 0) {
1723 countEventTmp->eventCount = 20283000 * 10;
1724 } else if (i == 4) {
1725 countEventTmp->eventCount = 2028300;
1726 } else if (i == 5) {
1727 countEventTmp->eventCount = 2000;
1728 } else if (i == 7) {
1729 countEventTmp->eventCount = 20;
1730 } else {
1731 countEventTmp->eventCount = 20283000;
1732 }
1733 countEventTmp->time_enabled = 2830280;
1734 countEventTmp->time_running = 2278140;
1735 countEventTmp->id = 0;
1736 countEventTmp->used_cpus = countEventTmp->eventCount / 1e9;
1737 }
1738 cmdStat.Report(countEvents);
1739 std::string stringOut = stdoutRecord.Stop();
1740 printf("output: %s\n", stringOut.c_str());
1741 EXPECT_EQ(FindExpectStr(stringOut, "G/sec"), true);
1742 EXPECT_EQ(FindExpectStr(stringOut, "M/sec"), true);
1743 EXPECT_EQ(FindExpectStr(stringOut, "K/sec"), true);
1744 EXPECT_EQ(FindExpectStr(stringOut, "/sec"), true);
1745 }
1746 } // namespace HiPerf
1747 } // namespace Developtools
1748 } // namespace OHOS
1749