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 <condition_variable>
20 #include <mutex>
21 #include <regex>
22 #include <sstream>
23 #include <thread>
24
25 #include <gmock/gmock.h>
26 #include <gtest/gtest.h>
27 #include <hilog/log.h>
28 #include <sched.h>
29
30 #include "perf_events.h"
31 #include "tracked_command.h"
32
33 using namespace testing::ext;
34 using namespace std;
35 using namespace OHOS::HiviewDFX;
36 namespace OHOS {
37 namespace Developtools {
38 namespace HiPerf {
39 static std::atomic<bool> g_wait = false;
40 class SubCommandStatTest : public testing::Test {
41 public:
42 static void SetUpTestCase(void);
43 static void TearDownTestCase(void);
44 void SetUp();
45 void TearDown();
46
47 static void TestCodeThread(int &tid);
48 bool FindExpectStr(const std::string &stringOut, const std::string &counterNames) const;
49 uint EffectiveCounter(const std::string &stringOut,
50 const std::vector<std::string> &counterNames,
51 uint &effectiveHeadCounter) const;
52 uint EffectiveCounter(const std::string &stringOut, const std::string &counterNames,
53 uint &effectiveHeadCounter) const;
54 int CounterValue(const std::string &stringOut, const std::string &configName) const;
55 void CheckGroupCoverage(const std::string &stringOut,
56 const std::string &groupCounterName) const;
57
58 const std::vector<std::string> defaultConfigNames_ = {
59 "hw-branch-misses",
60 "hw-cpu-cycles",
61 "hw-instructions",
62 #if defined(__aarch64__)
63 "hw-stalled-cycles-backend",
64 "hw-stalled-cycles-frontend",
65 #endif
66 "sw-context-switches",
67 "sw-page-faults",
68 "sw-task-clock",
69 };
70
71 const int defaultRunTimeoutMs = 4100;
72 const std::string timeReportStr = "Report at ";
73 static std::mutex mtx;
74 static std::condition_variable cv;
75 };
76
77 std::mutex SubCommandStatTest::mtx;
78 std::condition_variable SubCommandStatTest::cv;
79
SetUpTestCase()80 void SubCommandStatTest::SetUpTestCase() {}
81
TearDownTestCase()82 void SubCommandStatTest::TearDownTestCase() {}
83
SetUp()84 void SubCommandStatTest::SetUp()
85 {
86 ASSERT_EQ(SubCommand::GetSubCommands().size(), 0u);
87 ASSERT_EQ(RegisterSubCommandStat(), true);
88 }
89
TearDown()90 void SubCommandStatTest::TearDown()
91 {
92 SubCommand::ClearSubCommands();
93 ASSERT_EQ(SubCommand::GetSubCommands().size(), 0u);
94 }
95
TestCodeThread(int & tid)96 void SubCommandStatTest::TestCodeThread(int &tid)
97 {
98 std::vector<std::unique_ptr<char[]>> mems;
99 tid = gettid();
100 printf("TestCodeThread:%d ++\n", tid);
101
102 const int sum = 10;
103 const int num = 2;
104
105 constexpr size_t memSize {1024};
106 for (uint i = 0; i < sum * memSize; i++) {
107 if (i % num == 0) {
108 mems.push_back(std::make_unique<char[]>(memSize));
109 } else {
110 mems.push_back(std::make_unique<char[]>(memSize * num));
111 }
112 }
113
114 for (uint i = 0; i < sum * memSize; i++) {
115 mems.pop_back();
116 }
117 if (g_wait) {
118 std::unique_lock<std::mutex> lock(mtx);
119 cv.wait(lock);
120 }
121 printf("TestCodeThread:%d --\n", tid);
122 }
123
EffectiveCounter(const std::string & stringOut,const std::string & counterNames,uint & effectiveHeadCounter) const124 uint SubCommandStatTest::EffectiveCounter(const std::string &stringOut,
125 const std::string &counterNames,
126 uint &effectiveHeadCounter) const
127 {
128 std::string filterCounterNames {};
129 filterCounterNames = StringReplace(counterNames, ":u", "");
130 filterCounterNames = StringReplace(filterCounterNames, ":k", "");
131 return EffectiveCounter(stringOut, StringSplit(filterCounterNames, ","), effectiveHeadCounter);
132 }
133
FindExpectStr(const std::string & stringOut,const std::string & counterNames) const134 bool SubCommandStatTest::FindExpectStr(const std::string &stringOut,
135 const std::string &counterNames) const
136 {
137 auto lines = StringSplit(stringOut, "\n");
138 for (auto line : lines) {
139 if (line.find(counterNames.c_str()) != std::string::npos) {
140 return true;
141 }
142 }
143
144 return false;
145 }
146
EffectiveCounter(const std::string & stringOut,const std::vector<std::string> & counterNames,uint & effectiveHeadCounter) const147 uint SubCommandStatTest::EffectiveCounter(const std::string &stringOut,
148 const std::vector<std::string> &counterNames,
149 uint &effectiveHeadCounter) const
150 {
151 uint effectiveCounter = 0;
152 for (auto name : counterNames) {
153 EXPECT_NE(stringOut.find(name), std::string::npos);
154 }
155 auto lines = StringSplit(stringOut, "\n");
156 for (auto line : lines) {
157 if (line.find(timeReportStr.c_str()) != std::string::npos) {
158 printf("reset the count because found: '%s'\n", timeReportStr.c_str());
159 // reset the count
160 effectiveCounter = 0;
161 effectiveHeadCounter++;
162 continue;
163 }
164 auto tokens = StringSplit(line.c_str(), " ");
165 constexpr size_t sizeLimit {2};
166 std::regex pattern("^\\d+[,\\d{3}]*");
167 if (tokens.size() > sizeLimit &&
168 (IsDigits(tokens[0]) || std::regex_match(tokens[0], pattern))) {
169 if (find(counterNames.begin(), counterNames.end(), tokens[1]) != counterNames.end()) {
170 uint64_t count = std::stoull(tokens[0]);
171 effectiveCounter++;
172 printf("[%u] found %s:%s count %" PRIu64 "\n", effectiveCounter, tokens[1].c_str(),
173 tokens[0].c_str(), count);
174 }
175 }
176 }
177
178 // no more count than max
179 printf("effectiveCounter %u \n", effectiveCounter);
180 printf("effectiveHeadCounter %u \n", effectiveHeadCounter);
181
182 return effectiveCounter;
183 }
184
CounterValue(const std::string & stringOut,const std::string & configName) const185 int SubCommandStatTest::CounterValue(const std::string &stringOut,
186 const std::string &configName) const
187 {
188 int res {-1};
189 auto lines = StringSplit(stringOut, "\n");
190 for (auto line : lines) {
191 auto tokens = StringSplit(line.c_str(), " ");
192 constexpr size_t sizeLimit {2};
193 if (tokens.size() > sizeLimit and IsDigits(tokens[0])) {
194 if (tokens[1] == configName) {
195 uint64_t count = std::stoull(tokens[0]);
196 res += count;
197 }
198 }
199 }
200 if (res != -1) {
201 ++res;
202 }
203 return res;
204 }
205
CheckGroupCoverage(const std::string & stringOut,const std::string & groupCounterName) const206 void SubCommandStatTest::CheckGroupCoverage(const std::string &stringOut,
207 const std::string &groupCounterName) const
208 {
209 std::string filterGroupCounterName = StringReplace(groupCounterName, ":u", "");
210 filterGroupCounterName = StringReplace(filterGroupCounterName, ":k", "");
211 auto groupCounterNames = StringSplit(filterGroupCounterName, ",");
212
213 for (auto name : groupCounterNames) {
214 EXPECT_NE(stringOut.find(name), std::string::npos);
215 }
216 std::string groupCoverage;
217 auto lines = StringSplit(stringOut, "\n");
218 for (auto line : lines) {
219 auto tokens = StringSplit(line.c_str(), " ");
220 if (find(groupCounterNames.begin(), groupCounterNames.end(), tokens[1]) !=
221 groupCounterNames.end()) {
222 if (groupCoverage.empty()) {
223 groupCoverage = tokens.back();
224 } else {
225 EXPECT_EQ(groupCoverage, tokens.back());
226 }
227 }
228 }
229 }
230
231 /**
232 * @tc.name: TestOnSubCommand_a
233 * @tc.desc: -a
234 * @tc.type: FUNC
235 */
236 HWTEST_F(SubCommandStatTest, TestOnSubCommand_a, TestSize.Level1)
237 {
238 StdoutRecord stdoutRecord;
239 stdoutRecord.Start();
240 const auto startTime = chrono::steady_clock::now();
241 EXPECT_EQ(Command::DispatchCommand("stat -a -c 0 -d 3 --dumpoptions"), true);
242 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
243 chrono::steady_clock::now() - startTime);
244 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
245
246 std::string stringOut = stdoutRecord.Stop();
247 if (HasFailure()) {
248 printf("output:\n%s", stringOut.c_str());
249 }
250
251 // some times 'sw-page-faults' is 0
252 uint effectiveHeadCounter = 0;
253 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
254 (defaultConfigNames_.size() - 1));
255 }
256
257 /**
258 * @tc.name: TestOnSubCommand_a1
259 * @tc.desc: -a
260 * @tc.type: FUNC
261 */
262 HWTEST_F(SubCommandStatTest, TestOnSubCommand_a1, TestSize.Level1)
263 {
264 StdoutRecord stdoutRecord;
265 stdoutRecord.Start();
266 const auto startTime = chrono::steady_clock::now();
267 EXPECT_EQ(Command::DispatchCommand("stat -a -d 3 --dumpoptions"), true);
268 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
269 chrono::steady_clock::now() - startTime);
270 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
271
272 std::string stringOut = stdoutRecord.Stop();
273 printf("output:\n%s", stringOut.c_str());
274 if (HasFailure()) {
275 printf("output:\n%s", stringOut.c_str());
276 }
277
278 // some times 'sw-page-faults' is 0
279 uint effectiveHeadCounter = 0;
280 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
281 (defaultConfigNames_.size() - 1));
282 }
283
284 /**
285 * @tc.name: TestOnSubCommand_a2
286 * @tc.desc: -a
287 * @tc.type: FUNC
288 */
289 HWTEST_F(SubCommandStatTest, TestOnSubCommand_a2, TestSize.Level1)
290 {
291 StdoutRecord stdoutRecord;
292 stdoutRecord.Start();
293 const auto startTime = chrono::steady_clock::now();
294 EXPECT_EQ(Command::DispatchCommand("stat -a -d 3"), true);
295 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
296 chrono::steady_clock::now() - startTime);
297 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
298
299 std::string stringOut = stdoutRecord.Stop();
300 if (HasFailure()) {
301 printf("output:\n%s", stringOut.c_str());
302 }
303
304 // some times 'sw-page-faults' is 0
305 uint effectiveHeadCounter = 0;
306 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
307 (defaultConfigNames_.size() - 1));
308 }
309
310 /**
311 * @tc.name: TestOnSubCommand_a3
312 * @tc.desc: -a
313 * @tc.type: FUNC
314 */
315 HWTEST_F(SubCommandStatTest, TestOnSubCommand_a3, TestSize.Level1)
316 {
317 StdoutRecord stdoutRecord;
318 stdoutRecord.Start();
319 const auto startTime = chrono::steady_clock::now();
320 EXPECT_EQ(Command::DispatchCommand("stat -a -c 0 -d 3"), true);
321 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
322 chrono::steady_clock::now() - startTime);
323 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
324
325 std::string stringOut = stdoutRecord.Stop();
326 if (HasFailure()) {
327 printf("output:\n%s", stringOut.c_str());
328 }
329
330 // some times 'sw-page-faults' is 0
331 uint effectiveHeadCounter = 0;
332 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
333 (defaultConfigNames_.size() - 1));
334 }
335
336 /**
337 * @tc.name: TestOnSubCommand_a4
338 * @tc.desc: -a
339 * @tc.type: FUNC
340 */
341 HWTEST_F(SubCommandStatTest, TestOnSubCommand_a4, TestSize.Level1)
342 {
343 StdoutRecord stdoutRecord;
344 stdoutRecord.Start();
345 const auto startTime = chrono::steady_clock::now();
346 EXPECT_EQ(Command::DispatchCommand("stat -a test"), false);
347 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
348 chrono::steady_clock::now() - startTime);
349 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
350
351 std::string stringOut = stdoutRecord.Stop();
352 if (HasFailure()) {
353 printf("output:\n%s", stringOut.c_str());
354 }
355
356 // some times 'sw-page-faults' is 0
357 std::string expectStr = "failed";
358 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
359 }
360
361 /**
362 * @tc.name: TestOnSubCommand_c
363 * @tc.desc: -c
364 * @tc.type: FUNC
365 */
366 HWTEST_F(SubCommandStatTest, TestOnSubCommand_c, TestSize.Level1)
367 {
368 int tid1 = 0;
369 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
370
371 printf("wait child thread run.\n");
372 while (tid1 == 0) {
373 std::this_thread::sleep_for(std::chrono::milliseconds(10));
374 }
375 // we need bound us to cpu which we selelct
376 cpu_set_t mask, oldMask;
377 CPU_ZERO(&mask);
378 CPU_SET(1, &mask);
379
380 sched_getaffinity(0, sizeof(cpu_set_t), &oldMask);
381 sched_setaffinity(0, sizeof(cpu_set_t), &mask);
382 EXPECT_LE(CPU_COUNT(&mask), CPU_COUNT(&oldMask));
383
384 std::string cmdstr = "stat -p ";
385 cmdstr += std::to_string(tid1);
386 cmdstr += " -c 0 -d 3 --dumpoptions";
387
388 StdoutRecord stdoutRecord;
389 stdoutRecord.Start();
390 const auto startTime = chrono::steady_clock::now();
391 g_wait = true;
392 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
393 g_wait = false;
394 {
395 std::unique_lock<std::mutex> lock(mtx);
396 cv.notify_all();
397 }
398 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
399 chrono::steady_clock::now() - startTime);
400 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
401
402 std::string stringOut = stdoutRecord.Stop();
403 if (HasFailure()) {
404 printf("output:\n%s", stringOut.c_str());
405 }
406 // some times 'sw-page-faults' is 0
407 uint effectiveHeadCounter = 0u;
408 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
409 (defaultConfigNames_.size() - 1));
410
411 if (stringOut.find("event not support") == std::string::npos) {
412 EXPECT_NE(stringOut.find("Timeout exit"), std::string::npos);
413 }
414
415 sched_setaffinity(0, sizeof(cpu_set_t), &oldMask);
416 sched_getaffinity(0, sizeof(cpu_set_t), &mask);
417 EXPECT_EQ(CPU_COUNT(&mask), CPU_COUNT(&oldMask));
418 t1.join();
419 }
420
421 /**
422 * @tc.name: TestOnSubCommand_c1
423 * @tc.desc: -c
424 * @tc.type: FUNC
425 */
426 HWTEST_F(SubCommandStatTest, TestOnSubCommand_c1, TestSize.Level1)
427 {
428 int tid1 = 0;
429 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
430 while (tid1 == 0) {
431 std::this_thread::sleep_for(std::chrono::milliseconds(10));
432 }
433
434 std::string cmdstr = "stat -p ";
435 cmdstr += std::to_string(tid1);
436 cmdstr += " -c 1 -d 3";
437
438 StdoutRecord stdoutRecord;
439 stdoutRecord.Start();
440 const auto startTime = chrono::steady_clock::now();
441 g_wait = true;
442 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
443 g_wait = false;
444 {
445 std::unique_lock<std::mutex> lock(mtx);
446 cv.notify_all();
447 }
448 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
449 chrono::steady_clock::now() - startTime);
450 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
451
452 std::string stringOut = stdoutRecord.Stop();
453 if (HasFailure()) {
454 printf("output:\n%s", stringOut.c_str());
455 }
456
457 // some times 'sw-page-faults' is 0
458 uint effectiveHeadCounter = 0;
459 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
460 (defaultConfigNames_.size() - 1));
461 t1.join();
462 }
463
464 /**
465 * @tc.name: TestOnSubCommand_c2
466 * @tc.desc: -c
467 * @tc.type: FUNC
468 */
469 HWTEST_F(SubCommandStatTest, TestOnSubCommand_c2, TestSize.Level1)
470 {
471 int tid1 = 0;
472 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
473 while (tid1 == 0) {
474 std::this_thread::sleep_for(std::chrono::milliseconds(10));
475 }
476
477 std::string cmdstr = "stat -p ";
478 cmdstr += std::to_string(tid1);
479 cmdstr += " -c 0,1 -d 3";
480
481 StdoutRecord stdoutRecord;
482 stdoutRecord.Start();
483 const auto startTime = chrono::steady_clock::now();
484 g_wait = true;
485 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
486 g_wait = false;
487 {
488 std::unique_lock<std::mutex> lock(mtx);
489 cv.notify_all();
490 }
491 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
492 chrono::steady_clock::now() - startTime);
493 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
494
495 std::string stringOut = stdoutRecord.Stop();
496 if (HasFailure()) {
497 printf("output:\n%s", stringOut.c_str());
498 }
499
500 // some times 'sw-page-faults' is 0
501 uint effectiveHeadCounter = 0;
502 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
503 (defaultConfigNames_.size() - 1));
504 t1.join();
505 }
506
507 /**
508 * @tc.name: TestOnSubCommand_c3
509 * @tc.desc: -c
510 * @tc.type: FUNC
511 */
512 HWTEST_F(SubCommandStatTest, TestOnSubCommand_c3, TestSize.Level1)
513 {
514 StdoutRecord stdoutRecord;
515 stdoutRecord.Start();
516 const auto startTime = chrono::steady_clock::now();
517 EXPECT_EQ(Command::DispatchCommand("stat -a -c 0,1 -d 3"), true);
518 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
519 chrono::steady_clock::now() - startTime);
520 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
521
522 std::string stringOut = stdoutRecord.Stop();
523 if (HasFailure()) {
524 printf("output:\n%s", stringOut.c_str());
525 }
526
527 // some times 'sw-page-faults' is 0
528 uint effectiveHeadCounter = 0;
529 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
530 (defaultConfigNames_.size() - 1));
531 }
532
533 /**
534 * @tc.name: TestOnSubCommand_c4
535 * @tc.desc: -c
536 * @tc.type: FUNC
537 */
538 HWTEST_F(SubCommandStatTest, TestOnSubCommand_c4, TestSize.Level1)
539 {
540 int tid1 = 0;
541 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
542 while (tid1 == 0) {
543 std::this_thread::sleep_for(std::chrono::milliseconds(10));
544 }
545
546 std::string cmdstr = "stat -p ";
547 cmdstr += std::to_string(tid1);
548 cmdstr += " -c test -d 3";
549
550 StdoutRecord stdoutRecord;
551 stdoutRecord.Start();
552 const auto startTime = chrono::steady_clock::now();
553 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
554 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
555 chrono::steady_clock::now() - startTime);
556 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
557
558 std::string stringOut = stdoutRecord.Stop();
559 if (HasFailure()) {
560 printf("output:\n%s", stringOut.c_str());
561 }
562
563 // some times 'sw-page-faults' is 0
564 std::string expectStr = "incorrect option";
565 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
566 t1.join();
567 }
568
569 /**
570 * @tc.name: TestOnSubCommand_c5
571 * @tc.desc: -c
572 * @tc.type: FUNC
573 */
574 HWTEST_F(SubCommandStatTest, TestOnSubCommand_c5, TestSize.Level1)
575 {
576 int tid1 = 0;
577 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
578 while (tid1 == 0) {
579 std::this_thread::sleep_for(std::chrono::milliseconds(10));
580 }
581
582 std::string cmdstr = "stat -p ";
583 cmdstr += std::to_string(tid1);
584 cmdstr += " -c -2 -d 3";
585
586 StdoutRecord stdoutRecord;
587 stdoutRecord.Start();
588 const auto startTime = chrono::steady_clock::now();
589 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
590 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
591 chrono::steady_clock::now() - startTime);
592 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
593
594 std::string stringOut = stdoutRecord.Stop();
595 if (HasFailure()) {
596 printf("output:\n%s", stringOut.c_str());
597 }
598
599 // some times 'sw-page-faults' is 0
600 std::string expectStr = "Invalid -c value";
601 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
602 t1.join();
603 }
604
605 /**
606 * @tc.name: TestOnSubCommand_d
607 * @tc.desc: -d
608 * @tc.type: FUNC
609 */
610 HWTEST_F(SubCommandStatTest, TestOnSubCommand_d, TestSize.Level1)
611 {
612 int tid1 = 0;
613 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
614 while (tid1 == 0) {
615 std::this_thread::sleep_for(std::chrono::milliseconds(10));
616 }
617
618 std::string cmdstr = "stat -p ";
619 cmdstr += std::to_string(tid1);
620 cmdstr += " -c 0 -d 3 --dumpoptions";
621
622 StdoutRecord stdoutRecord;
623 stdoutRecord.Start();
624 const auto startTime = chrono::steady_clock::now();
625 g_wait = true;
626 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
627 g_wait = false;
628 {
629 std::unique_lock<std::mutex> lock(mtx);
630 cv.notify_all();
631 }
632 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
633 chrono::steady_clock::now() - startTime);
634 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
635
636 std::string stringOut = stdoutRecord.Stop();
637 if (HasFailure()) {
638 printf("output:\n%s", stringOut.c_str());
639 }
640 // some times 'sw-page-faults' is 0
641 uint effectiveHeadCounter = 0u;
642 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
643 (defaultConfigNames_.size() - 1));
644 t1.join();
645 }
646
647 /**
648 * @tc.name: TestOnSubCommand_p
649 * @tc.desc: -p
650 * @tc.type: FUNC
651 */
652 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p, TestSize.Level1)
653 {
654 int tid1 = 0;
655 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
656 while (tid1 == 0) {
657 std::this_thread::sleep_for(std::chrono::milliseconds(10));
658 }
659
660 std::string cmdstr = "stat -p -1 -d 3";
661
662 StdoutRecord stdoutRecord;
663 stdoutRecord.Start();
664 const auto startTime = chrono::steady_clock::now();
665 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
666 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
667 chrono::steady_clock::now() - startTime);
668 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
669
670 std::string stringOut = stdoutRecord.Stop();
671 if (HasFailure()) {
672 printf("output:\n%s", stringOut.c_str());
673 }
674
675 // some times 'sw-page-faults' is 0
676 std::string expectStr = "Invalid -p value";
677 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
678 t1.join();
679 }
680
681 /**
682 * @tc.name: TestOnSubCommand_p
683 * @tc.desc: -p
684 * @tc.type: FUNC
685 */
686 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p1, TestSize.Level1)
687 {
688 int tid1 = 0;
689 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
690 while (tid1 == 0) {
691 std::this_thread::sleep_for(std::chrono::milliseconds(10));
692 }
693
694 std::string cmdstr = "stat -a --app test -d 3";
695
696 StdoutRecord stdoutRecord;
697 stdoutRecord.Start();
698 const auto startTime = chrono::steady_clock::now();
699 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
700 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
701 chrono::steady_clock::now() - startTime);
702 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
703
704 std::string stringOut = stdoutRecord.Stop();
705 if (HasFailure()) {
706 printf("output:\n%s", stringOut.c_str());
707 }
708
709 // some times 'sw-page-faults' is 0
710 std::string expectStr = "You cannot specify -a and --app at the same time";
711 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
712 t1.join();
713 }
714
715 /**
716 * @tc.name: TestOnSubCommand_p2
717 * @tc.desc: -p
718 * @tc.type: FUNC
719 */
720 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p2, TestSize.Level1)
721 {
722 int tid1 = 0;
723 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
724 while (tid1 == 0) {
725 std::this_thread::sleep_for(std::chrono::milliseconds(10));
726 }
727
728 std::string cmdstr = "stat --app test -p 1234 -d 3";
729
730 StdoutRecord stdoutRecord;
731 stdoutRecord.Start();
732 const auto startTime = chrono::steady_clock::now();
733 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
734 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
735 chrono::steady_clock::now() - startTime);
736 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
737
738 std::string stringOut = stdoutRecord.Stop();
739 if (HasFailure()) {
740 printf("output:\n%s", stringOut.c_str());
741 }
742
743 // some times 'sw-page-faults' is 0
744 std::string expectStr = "You cannot specify --app and -t/-p at the same time";
745 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
746 t1.join();
747 }
748
749 /**
750 * @tc.name: TestOnSubCommand_chkms
751 * @tc.desc: --chkms
752 * @tc.type: FUNC
753 */
754 HWTEST_F(SubCommandStatTest, TestOnSubCommand_ch, TestSize.Level1)
755 {
756 int tid1 = 0;
757 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
758 while (tid1 == 0) {
759 std::this_thread::sleep_for(std::chrono::milliseconds(10));
760 }
761
762 std::string cmdstr = "stat -a -d 3 --chkms 201";
763
764 StdoutRecord stdoutRecord;
765 stdoutRecord.Start();
766 const auto startTime = chrono::steady_clock::now();
767 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
768 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
769 chrono::steady_clock::now() - startTime);
770 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
771
772 std::string stringOut = stdoutRecord.Stop();
773 if (HasFailure()) {
774 printf("output:\n%s", stringOut.c_str());
775 }
776
777 // some times 'sw-page-faults' is 0
778 std::string expectStr = "Invalid --chkms value '201'";
779 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
780 t1.join();
781 }
782
783 /**
784 * @tc.name: TestOnSubCommand_aa
785 * @tc.desc: aa
786 * @tc.type: FUNC
787 */
788 HWTEST_F(SubCommandStatTest, TestOnSubCommand_aa, 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 aa --app 123 -d 3";
797
798 StdoutRecord stdoutRecord;
799 stdoutRecord.Start();
800 const auto startTime = chrono::steady_clock::now();
801 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
802 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
803 chrono::steady_clock::now() - startTime);
804 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
805
806 std::string stringOut = stdoutRecord.Stop();
807 if (HasFailure()) {
808 printf("output:\n%s", stringOut.c_str());
809 }
810
811 // some times 'sw-page-faults' is 0
812 std::string expectStr = "You cannot specify a cmd and --app at the same time";
813 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
814 t1.join();
815 }
816
817 /**
818 * @tc.name: TestOnSubCommand_d1
819 * @tc.desc: -d
820 * @tc.type: FUNC
821 */
822 HWTEST_F(SubCommandStatTest, TestOnSubCommand_d1, TestSize.Level1)
823 {
824 StdoutRecord stdoutRecord;
825 stdoutRecord.Start();
826 const auto startTime = chrono::steady_clock::now();
827 EXPECT_EQ(Command::DispatchCommand("stat -a -d 3 --dumpoptions"), true);
828 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
829 chrono::steady_clock::now() - startTime);
830 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
831
832 std::string stringOut = stdoutRecord.Stop();
833 if (HasFailure()) {
834 printf("output:\n%s", stringOut.c_str());
835 }
836 // some times 'sw-page-faults' is 0
837 uint effectiveHeadCounter = 0u;
838 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
839 (defaultConfigNames_.size() - 1));
840 }
841
842 /**
843 * @tc.name: TestOnSubCommand_d2
844 * @tc.desc: -d
845 * @tc.type: FUNC
846 */
847 HWTEST_F(SubCommandStatTest, TestOnSubCommand_d2, TestSize.Level1)
848 {
849 int tid1 = 0;
850 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
851 while (tid1 == 0) {
852 std::this_thread::sleep_for(std::chrono::milliseconds(10));
853 }
854
855 std::string cmdstr = "stat -p ";
856 cmdstr += std::to_string(tid1);
857 cmdstr += " -d -1";
858
859 StdoutRecord stdoutRecord;
860 stdoutRecord.Start();
861 const auto startTime = chrono::steady_clock::now();
862 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
863 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
864 chrono::steady_clock::now() - startTime);
865 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
866
867 std::string stringOut = stdoutRecord.Stop();
868 if (HasFailure()) {
869 printf("output:\n%s", stringOut.c_str());
870 }
871 // some times 'sw-page-faults' is 0
872 std::string expectStr = "failed";
873 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
874 t1.join();
875 }
876
877 /**
878 * @tc.name: TestOnSubCommand_d3
879 * @tc.desc: -d
880 * @tc.type: FUNC
881 */
882 HWTEST_F(SubCommandStatTest, TestOnSubCommand_d3, TestSize.Level1)
883 {
884 int tid1 = 0;
885 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
886 while (tid1 == 0) {
887 std::this_thread::sleep_for(std::chrono::milliseconds(10));
888 }
889
890 std::string cmdstr = "stat -p ";
891 cmdstr += std::to_string(tid1);
892 cmdstr += " -d test";
893
894 StdoutRecord stdoutRecord;
895 stdoutRecord.Start();
896 const auto startTime = chrono::steady_clock::now();
897 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
898 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
899 chrono::steady_clock::now() - startTime);
900 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
901
902 std::string stringOut = stdoutRecord.Stop();
903 if (HasFailure()) {
904 printf("output:\n%s", stringOut.c_str());
905 }
906 // some times 'sw-page-faults' is 0
907 std::string expectStr = "incorrect option";
908 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
909 t1.join();
910 }
911
912 /**
913 * @tc.name: TestOnSubCommand_d4
914 * @tc.desc: -d
915 * @tc.type: FUNC
916 */
917 HWTEST_F(SubCommandStatTest, TestOnSubCommand_d4, TestSize.Level1)
918 {
919 int tid1 = 0;
920 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
921 while (tid1 == 0) {
922 std::this_thread::sleep_for(std::chrono::milliseconds(10));
923 }
924
925 std::string cmdstr = "stat -p ";
926 cmdstr += std::to_string(tid1);
927 cmdstr += " -c 0,1 -d 1";
928
929 StdoutRecord stdoutRecord;
930 stdoutRecord.Start();
931 const auto startTime = chrono::steady_clock::now();
932 g_wait = true;
933 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
934 g_wait = false;
935 {
936 std::unique_lock<std::mutex> lock(mtx);
937 cv.notify_all();
938 }
939 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
940 chrono::steady_clock::now() - startTime);
941 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
942
943 std::string stringOut = stdoutRecord.Stop();
944 if (HasFailure()) {
945 printf("output:\n%s", stringOut.c_str());
946 }
947 // some times 'sw-page-faults' is 0
948 uint effectiveHeadCounter = 0u;
949 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
950 (defaultConfigNames_.size() - 1));
951 t1.join();
952 }
953
954
955 /**
956 * @tc.name: TestOnSubCommand_d5
957 * @tc.desc: -d
958 * @tc.type: FUNC
959 */
960 HWTEST_F(SubCommandStatTest, TestOnSubCommand_d5, TestSize.Level1)
961 {
962 int tid1 = 0;
963 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
964 while (tid1 == 0) {
965 std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 10: sleep 10ms
966 }
967
968 std::string cmdstr = "stat -p ";
969 cmdstr += std::to_string(tid1);
970 cmdstr += " -c 0 -d 3 --dumpoptions --per-core";
971
972 StdoutRecord stdoutRecord;
973 stdoutRecord.Start();
974 const auto startTime = chrono::steady_clock::now();
975 g_wait = true;
976 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
977 g_wait = false;
978 {
979 std::unique_lock<std::mutex> lock(mtx);
980 cv.notify_all();
981 }
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 t1.join();
991 }
992
993 /**
994 * @tc.name: TestOnSubCommand_d6
995 * @tc.desc: -d
996 * @tc.type: FUNC
997 */
998 HWTEST_F(SubCommandStatTest, TestOnSubCommand_d6, TestSize.Level1)
999 {
1000 int tid1 = 0;
1001 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1002 while (tid1 == 0) {
1003 std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 10: sleep 10ms
1004 }
1005
1006 std::string cmdstr = "stat -p ";
1007 cmdstr += std::to_string(tid1);
1008 cmdstr += " -c 0 -d 3 --dumpoptions --per-thread";
1009
1010 StdoutRecord stdoutRecord;
1011 stdoutRecord.Start();
1012 const auto startTime = chrono::steady_clock::now();
1013 g_wait = true;
1014 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1015 g_wait = false;
1016 {
1017 std::unique_lock<std::mutex> lock(mtx);
1018 cv.notify_all();
1019 }
1020 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1021 chrono::steady_clock::now() - startTime);
1022 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1023
1024 std::string stringOut = stdoutRecord.Stop();
1025 if (HasFailure()) {
1026 printf("output:\n%s", stringOut.c_str());
1027 }
1028 t1.join();
1029 }
1030
1031 /**
1032 * @tc.name: TestOnSubCommand_i
1033 * @tc.desc: -i
1034 * @tc.type: FUNC
1035 */
1036 HWTEST_F(SubCommandStatTest, TestOnSubCommand_i, 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 += " -c 0 -d 3 -i 1000 --dumpoptions";
1047
1048 StdoutRecord stdoutRecord;
1049 stdoutRecord.Start();
1050 const auto startTime = chrono::steady_clock::now();
1051 g_wait = true;
1052 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1053 g_wait = false;
1054 {
1055 std::unique_lock<std::mutex> lock(mtx);
1056 cv.notify_all();
1057 }
1058 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1059 chrono::steady_clock::now() - startTime);
1060 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1061
1062 std::string stringOut = stdoutRecord.Stop();
1063 if (HasFailure()) {
1064 printf("output:\n%s", stringOut.c_str());
1065 }
1066 // some times 'sw-page-faults' is 0
1067 uint effectiveHeadCounter = 0u;
1068 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
1069 (defaultConfigNames_.size() - 1));
1070
1071 if (stringOut.find("event not support") == std::string::npos) {
1072 EXPECT_GE(effectiveHeadCounter, 3u);
1073 }
1074 t1.join();
1075 }
1076
1077 /**
1078 * @tc.name: TestOnSubCommand_i1
1079 * @tc.desc: -i
1080 * @tc.type: FUNC
1081 */
1082 HWTEST_F(SubCommandStatTest, TestOnSubCommand_i1, TestSize.Level1)
1083 {
1084 int tid1 = 0;
1085 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1086 while (tid1 == 0) {
1087 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1088 }
1089
1090 std::string cmdstr = "stat -p ";
1091 cmdstr += std::to_string(tid1);
1092 cmdstr += " -c 0 -d 3 -i 500 --dumpoptions";
1093
1094 StdoutRecord stdoutRecord;
1095 stdoutRecord.Start();
1096 const auto startTime = chrono::steady_clock::now();
1097 g_wait = true;
1098 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1099 g_wait = false;
1100 {
1101 std::unique_lock<std::mutex> lock(mtx);
1102 cv.notify_all();
1103 }
1104 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1105 chrono::steady_clock::now() - startTime);
1106 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1107
1108 std::string stringOut = stdoutRecord.Stop();
1109 if (HasFailure()) {
1110 printf("output:\n%s", stringOut.c_str());
1111 }
1112 // some times 'sw-page-faults' is 0
1113 uint effectiveHeadCounter = 0u;
1114 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
1115 (defaultConfigNames_.size() - 1));
1116
1117 EXPECT_GE(effectiveHeadCounter, 3u);
1118 t1.join();
1119 }
1120
1121 /**
1122 * @tc.name: TestOnSubCommand_i2
1123 * @tc.desc: -i
1124 * @tc.type: FUNC
1125 */
1126 HWTEST_F(SubCommandStatTest, TestOnSubCommand_i2, TestSize.Level1)
1127 {
1128 int tid1 = 0;
1129 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1130 while (tid1 == 0) {
1131 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1132 }
1133
1134 std::string cmdstr = "stat -p ";
1135 cmdstr += std::to_string(tid1);
1136 cmdstr += " -c 0 -d 3 -i -1 --dumpoptions";
1137
1138 StdoutRecord stdoutRecord;
1139 stdoutRecord.Start();
1140 const auto startTime = chrono::steady_clock::now();
1141 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
1142 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1143 chrono::steady_clock::now() - startTime);
1144 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1145
1146 std::string stringOut = stdoutRecord.Stop();
1147 if (HasFailure()) {
1148 printf("output:\n%s", stringOut.c_str());
1149 }
1150 // some times 'sw-page-faults' is 0
1151 std::string expectStr = "failed";
1152 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1153 t1.join();
1154 }
1155
1156 /**
1157 * @tc.name: TestOnSubCommand_i2
1158 * @tc.desc: -i
1159 * @tc.type: FUNC
1160 */
1161 HWTEST_F(SubCommandStatTest, TestOnSubCommand_i3, TestSize.Level1)
1162 {
1163 int tid1 = 0;
1164 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1165 while (tid1 == 0) {
1166 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1167 }
1168
1169 std::string cmdstr = "stat -p ";
1170 cmdstr += std::to_string(tid1);
1171 cmdstr += " -c 0 -d 3 -i test --dumpoptions";
1172
1173 StdoutRecord stdoutRecord;
1174 stdoutRecord.Start();
1175 const auto startTime = chrono::steady_clock::now();
1176 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
1177 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1178 chrono::steady_clock::now() - startTime);
1179 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1180
1181 std::string stringOut = stdoutRecord.Stop();
1182 if (HasFailure()) {
1183 printf("output:\n%s", stringOut.c_str());
1184 }
1185 // some times 'sw-page-faults' is 0
1186 std::string expectStr = "incorrect";
1187 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1188 t1.join();
1189 }
1190
1191 /**
1192 * @tc.name: TestOnSubCommand_i4
1193 * @tc.desc: -i
1194 * @tc.type: FUNC
1195 */
1196 HWTEST_F(SubCommandStatTest, TestOnSubCommand_i4, TestSize.Level1)
1197 {
1198 int tid1 = 0;
1199 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1200 while (tid1 == 0) {
1201 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1202 }
1203
1204 std::string cmdstr = "stat -p ";
1205 cmdstr += std::to_string(tid1);
1206 cmdstr += " -c 0 -d 1 -i 100 --dumpoptions";
1207
1208 StdoutRecord stdoutRecord;
1209 stdoutRecord.Start();
1210 const auto startTime = chrono::steady_clock::now();
1211 g_wait = true;
1212 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1213 g_wait = false;
1214 {
1215 std::unique_lock<std::mutex> lock(mtx);
1216 cv.notify_all();
1217 }
1218 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1219 chrono::steady_clock::now() - startTime);
1220 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1221
1222 std::string stringOut = stdoutRecord.Stop();
1223 if (HasFailure()) {
1224 printf("output:\n%s", stringOut.c_str());
1225 }
1226 // some times 'sw-page-faults' is 0
1227 uint effectiveHeadCounter = 0u;
1228 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
1229 (defaultConfigNames_.size() - 1));
1230
1231 EXPECT_GE(effectiveHeadCounter, 3u);
1232 t1.join();
1233 }
1234
1235 /**
1236 * @tc.name: TestOnSubCommand_e
1237 * @tc.desc: -e261
1238 * @tc.type: FUNC
1239 */
1240 HWTEST_F(SubCommandStatTest, TestOnSubCommand_e, TestSize.Level1)
1241 {
1242 int tid1 = 0;
1243 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1244 while (tid1 == 0) {
1245 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1246 }
1247
1248 std::string cmdstr = "stat -p ";
1249 cmdstr += std::to_string(tid1);
1250 cmdstr += " -e hw-instructions -c 0 -d 3 --dumpoptions";
1251
1252 StdoutRecord stdoutRecord;
1253 stdoutRecord.Start();
1254 const auto startTime = chrono::steady_clock::now();
1255 g_wait = true;
1256 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1257 g_wait = false;
1258 {
1259 std::unique_lock<std::mutex> lock(mtx);
1260 cv.notify_all();
1261 }
1262 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1263 chrono::steady_clock::now() - startTime);
1264 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1265
1266 std::string stringOut = stdoutRecord.Stop();
1267 if (HasFailure()) {
1268 printf("output:\n%s", stringOut.c_str());
1269 }
1270 const std::vector<std::string> configNmaes = {"hw-instructions"};
1271 uint effectiveHeadCounter = 0u;
1272 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1273 t1.join();
1274 }
1275
1276 /**
1277 * @tc.name: TestOnSubCommand_e1
1278 * @tc.desc: -e261
1279 * @tc.type: FUNC
1280 */
1281 HWTEST_F(SubCommandStatTest, TestOnSubCommand_e1, TestSize.Level1)
1282 {
1283 int tid1 = 0;
1284 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1285 while (tid1 == 0) {
1286 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1287 }
1288
1289 std::string cmdstr = "stat -p ";
1290 cmdstr += std::to_string(tid1);
1291 cmdstr += " -e hw-branch-misses -c 0 -d 3 --dumpoptions";
1292
1293 StdoutRecord stdoutRecord;
1294 stdoutRecord.Start();
1295 const auto startTime = chrono::steady_clock::now();
1296 g_wait = true;
1297 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1298 g_wait = false;
1299 {
1300 std::unique_lock<std::mutex> lock(mtx);
1301 cv.notify_all();
1302 }
1303 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1304 chrono::steady_clock::now() - startTime);
1305 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1306
1307 std::string stringOut = stdoutRecord.Stop();
1308 if (HasFailure()) {
1309 printf("output:\n%s", stringOut.c_str());
1310 }
1311 const std::vector<std::string> configNmaes = {"hw-branch-misses"};
1312 uint effectiveHeadCounter = 0u;
1313 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1314 t1.join();
1315 }
1316
1317 /**
1318 * @tc.name: TestOnSubCommand_e2
1319 * @tc.desc: -e261
1320 * @tc.type: FUNC
1321 */
1322 HWTEST_F(SubCommandStatTest, TestOnSubCommand_e2, TestSize.Level1)
1323 {
1324 int tid1 = 0;
1325 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1326 while (tid1 == 0) {
1327 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1328 }
1329
1330 std::string cmdstr = "stat -p ";
1331 cmdstr += std::to_string(tid1);
1332 cmdstr += " -e hw-cpu-cycles -c 0 -d 3 --dumpoptions";
1333
1334 StdoutRecord stdoutRecord;
1335 stdoutRecord.Start();
1336 const auto startTime = chrono::steady_clock::now();
1337 g_wait = true;
1338 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1339 g_wait = false;
1340 {
1341 std::unique_lock<std::mutex> lock(mtx);
1342 cv.notify_all();
1343 }
1344 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1345 chrono::steady_clock::now() - startTime);
1346 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1347
1348 std::string stringOut = stdoutRecord.Stop();
1349 if (HasFailure()) {
1350 printf("output:\n%s", stringOut.c_str());
1351 }
1352 const std::vector<std::string> configNmaes = {"hw-cpu-cycles"};
1353 uint effectiveHeadCounter = 0u;
1354 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1355 t1.join();
1356 }
1357
1358 /**
1359 * @tc.name: TestOnSubCommand_e3
1360 * @tc.desc: -e261
1361 * @tc.type: FUNC
1362 */
1363 HWTEST_F(SubCommandStatTest, TestOnSubCommand_e3, TestSize.Level1)
1364 {
1365 int tid1 = 0;
1366 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1367 while (tid1 == 0) {
1368 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1369 }
1370
1371 std::string cmdstr = "stat -p ";
1372 cmdstr += std::to_string(tid1);
1373 cmdstr += " -e hw-instructions -c 0 -d 3 --dumpoptions";
1374
1375 StdoutRecord stdoutRecord;
1376 stdoutRecord.Start();
1377 const auto startTime = chrono::steady_clock::now();
1378 g_wait = true;
1379 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1380 g_wait = false;
1381 {
1382 std::unique_lock<std::mutex> lock(mtx);
1383 cv.notify_all();
1384 }
1385 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1386 chrono::steady_clock::now() - startTime);
1387 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1388
1389 std::string stringOut = stdoutRecord.Stop();
1390 if (HasFailure()) {
1391 printf("output:\n%s", stringOut.c_str());
1392 }
1393 const std::vector<std::string> configNmaes = {"hw-instructions"};
1394 uint effectiveHeadCounter = 0u;
1395 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1396 t1.join();
1397 }
1398
1399 /**
1400 * @tc.name: TestOnSubCommand_e4
1401 * @tc.desc: -e261
1402 * @tc.type: FUNC
1403 */
1404 HWTEST_F(SubCommandStatTest, TestOnSubCommand_e4, TestSize.Level1)
1405 {
1406 int tid1 = 0;
1407 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1408 while (tid1 == 0) {
1409 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1410 }
1411
1412 std::string cmdstr = "stat -p ";
1413 cmdstr += std::to_string(tid1);
1414 cmdstr += " -e hw-branch-test -c 0 -d 3 --dumpoptions";
1415
1416 StdoutRecord stdoutRecord;
1417 stdoutRecord.Start();
1418 const auto startTime = chrono::steady_clock::now();
1419 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
1420 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1421 chrono::steady_clock::now() - startTime);
1422 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1423
1424 std::string stringOut = stdoutRecord.Stop();
1425 if (HasFailure()) {
1426 printf("output:\n%s", stringOut.c_str());
1427 }
1428 std::string expectStr = "event is not supported";
1429 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1430 t1.join();
1431 }
1432
1433 /**
1434 * @tc.name: TestOnSubCommand_g
1435 * @tc.desc: -g
1436 * @tc.type: FUNC
1437 */
1438 HWTEST_F(SubCommandStatTest, TestOnSubCommand_g, TestSize.Level1)
1439 {
1440 int tid1 = 0;
1441 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1442 while (tid1 == 0) {
1443 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1444 }
1445
1446 std::string cmdstr = "stat -p ";
1447 cmdstr += std::to_string(tid1);
1448 cmdstr += " -g hw-branch-misses"
1449 " -g hw-cpu-cycles,hw-instructions"
1450 " -c 0 -d 3 --dumpoptions";
1451
1452 StdoutRecord stdoutRecord;
1453 stdoutRecord.Start();
1454 const auto startTime = chrono::steady_clock::now();
1455 g_wait = true;
1456 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1457 g_wait = false;
1458 {
1459 std::unique_lock<std::mutex> lock(mtx);
1460 cv.notify_all();
1461 }
1462 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1463 chrono::steady_clock::now() - startTime);
1464 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1465
1466 const std::string stringOut = stdoutRecord.Stop();
1467 if (HasFailure()) {
1468 printf("output:\n%s", stringOut.c_str());
1469 }
1470
1471 const std::vector<std::string> configNmaes = {
1472 "hw-branch-misses",
1473 "hw-cpu-cycles",
1474 "hw-instructions",
1475 };
1476 uint effectiveHeadCounter = 0u;
1477 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1478 t1.join();
1479 }
1480
1481 /**
1482 * @tc.name: TestOnSubCommand_g1
1483 * @tc.desc: -g
1484 * @tc.type: FUNC
1485 */
1486 HWTEST_F(SubCommandStatTest, TestOnSubCommand_g1, TestSize.Level1)
1487 {
1488 int tid1 = 0;
1489 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1490 while (tid1 == 0) {
1491 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1492 }
1493
1494 std::string cmdstr = "stat -p ";
1495 cmdstr += std::to_string(tid1);
1496 cmdstr += " -g hw-instructions,hw-branch-misses"
1497 " -c 0 -d 3 --dumpoptions";
1498
1499 StdoutRecord stdoutRecord;
1500 stdoutRecord.Start();
1501 const auto startTime = chrono::steady_clock::now();
1502 g_wait = true;
1503 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1504 g_wait = false;
1505 {
1506 std::unique_lock<std::mutex> lock(mtx);
1507 cv.notify_all();
1508 }
1509 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1510 chrono::steady_clock::now() - startTime);
1511 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1512
1513 const std::string stringOut = stdoutRecord.Stop();
1514 if (HasFailure()) {
1515 printf("output:\n%s", stringOut.c_str());
1516 }
1517
1518 const std::vector<std::string> configNmaes = {
1519 "hw-instructions",
1520 "hw-branch-misses",
1521 };
1522 uint effectiveHeadCounter = 0u;
1523 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1524 t1.join();
1525 }
1526
1527 /**
1528 * @tc.name: TestOnSubCommand_g2
1529 * @tc.desc: -g
1530 * @tc.type: FUNC
1531 */
1532 HWTEST_F(SubCommandStatTest, TestOnSubCommand_g2, TestSize.Level1)
1533 {
1534 int tid1 = 0;
1535 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1536 while (tid1 == 0) {
1537 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1538 }
1539
1540 std::string cmdstr = "stat -p ";
1541 cmdstr += std::to_string(tid1);
1542 cmdstr += " -g hw-cpu-cycles,hw-instructions"
1543 " -c 0 -d 3 --dumpoptions";
1544
1545 StdoutRecord stdoutRecord;
1546 stdoutRecord.Start();
1547 const auto startTime = chrono::steady_clock::now();
1548 g_wait = true;
1549 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1550 g_wait = false;
1551 {
1552 std::unique_lock<std::mutex> lock(mtx);
1553 cv.notify_all();
1554 }
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 const std::string stringOut = stdoutRecord.Stop();
1560 if (HasFailure()) {
1561 printf("output:\n%s", stringOut.c_str());
1562 }
1563
1564 const std::vector<std::string> configNmaes = {
1565 "hw-cpu-cycles",
1566 "hw-instructions",
1567 };
1568 uint effectiveHeadCounter = 0u;
1569 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1570 t1.join();
1571 }
1572
1573 /**
1574 * @tc.name: TestOnSubCommand_g3
1575 * @tc.desc: -g
1576 * @tc.type: FUNC
1577 */
1578 HWTEST_F(SubCommandStatTest, TestOnSubCommand_g3, TestSize.Level1)
1579 {
1580 int tid1 = 0;
1581 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1582 while (tid1 == 0) {
1583 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1584 }
1585
1586 std::string cmdstr = "stat -p ";
1587 cmdstr += std::to_string(tid1);
1588 cmdstr += " -g hw-cpu-test,hw-instructions"
1589 " -c 0 -d 3 --dumpoptions";
1590
1591 StdoutRecord stdoutRecord;
1592 stdoutRecord.Start();
1593 const auto startTime = chrono::steady_clock::now();
1594 EXPECT_EQ(Command::DispatchCommand(cmdstr), false);
1595 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1596 chrono::steady_clock::now() - startTime);
1597 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1598
1599 const std::string stringOut = stdoutRecord.Stop();
1600 if (HasFailure()) {
1601 printf("output:\n%s", stringOut.c_str());
1602 }
1603
1604 std::string expectStr = "event is not supported";
1605 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1606 t1.join();
1607 }
1608
1609 /**
1610 * @tc.name: TestOnSubCommand_g_uk
1611 * @tc.desc: -g u:k
1612 * @tc.type: FUNC
1613 */
1614 HWTEST_F(SubCommandStatTest, TestOnSubCommand_g_uk, TestSize.Level1)
1615 {
1616 int tid1 = 0;
1617 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1618 while (tid1 == 0) {
1619 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1620 }
1621
1622 std::string cmdstr = "stat -p ";
1623 cmdstr += std::to_string(tid1);
1624 cmdstr += " -g hw-branch-misses:k"
1625 " -g hw-cpu-cycles:k,hw-instructions:k"
1626 " -c 0 -d 3 --dumpoptions";
1627
1628 StdoutRecord stdoutRecord;
1629 stdoutRecord.Start();
1630 const auto startTime = chrono::steady_clock::now();
1631 g_wait = true;
1632 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1633 g_wait = false;
1634 {
1635 std::unique_lock<std::mutex> lock(mtx);
1636 cv.notify_all();
1637 }
1638 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1639 chrono::steady_clock::now() - startTime);
1640 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1641
1642 std::string stringOut = stdoutRecord.Stop();
1643 if (HasFailure()) {
1644 printf("output:\n%s", stringOut.c_str());
1645 }
1646 const std::vector<std::string> configNmaes = {
1647 "hw-branch-misses:k",
1648 "hw-cpu-cycles:k",
1649 "hw-instructions:k",
1650 };
1651 // some times 'sw-page-faults' is 0
1652 uint effectiveHeadCounter = 0u;
1653 EXPECT_GE(EffectiveCounter(stringOut, configNmaes, effectiveHeadCounter), configNmaes.size());
1654 CheckGroupCoverage(stringOut, "hw-branch-misses:k");
1655 CheckGroupCoverage(stringOut, "hw-cpu-cycles:k,hw-instructions:k");
1656 t1.join();
1657 }
1658
1659 /**
1660 * @tc.name: TestOnSubCommand_p_t
1661 * @tc.desc: -p -t
1662 * @tc.type: FUNC
1663 */
1664 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p_t, TestSize.Level1)
1665 {
1666 int tid1 = 0;
1667 int tid2 = 0;
1668 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1669 std::thread t2(SubCommandStatTest::TestCodeThread, std::ref(tid2));
1670
1671 printf("wait child thread run.\n");
1672 while (tid1 * tid2 == 0) {
1673 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1674 }
1675
1676 StdoutRecord stdoutRecord;
1677 stdoutRecord.Start();
1678 const auto startTime = chrono::steady_clock::now();
1679
1680 std::string tidString = " -t ";
1681 tidString += std::to_string(tid1) + ",";
1682 tidString += std::to_string(tid2);
1683
1684 std::string cmdString = "stat";
1685 cmdString += tidString;
1686 cmdString += " -c 0 -d 3 --dumpoptions";
1687 g_wait = true;
1688 EXPECT_EQ(Command::DispatchCommand(cmdString), true);
1689 g_wait = false;
1690 {
1691 std::unique_lock<std::mutex> lock(mtx);
1692 cv.notify_all();
1693 }
1694 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1695 chrono::steady_clock::now() - startTime);
1696 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1697
1698 std::string stringOut = stdoutRecord.Stop();
1699 if (HasFailure()) {
1700 printf("output:\n%s", stringOut.c_str());
1701 }
1702 // some times 'sw-page-faults' is 0
1703 uint effectiveHeadCounter = 0u;
1704 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
1705 (defaultConfigNames_.size() - 1));
1706
1707 t1.join();
1708 t2.join();
1709 }
1710
1711 /**
1712 * @tc.name: TestOnSubCommand_p_t1
1713 * @tc.desc: -p -t
1714 * @tc.type: FUNC
1715 */
1716 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p_t1, TestSize.Level1)
1717 {
1718 int tid1 = 0;
1719 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1720 while (tid1 == 0) {
1721 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1722 }
1723
1724 StdoutRecord stdoutRecord;
1725 stdoutRecord.Start();
1726 const auto startTime = chrono::steady_clock::now();
1727
1728 std::string tidString = " -t ";
1729 tidString += std::to_string(tid1);
1730
1731 std::string cmdString = "stat";
1732 cmdString += tidString;
1733 cmdString += " -c 0 -d 3 --dumpoptions";
1734 g_wait = true;
1735 EXPECT_EQ(Command::DispatchCommand(cmdString), true);
1736 g_wait = false;
1737 {
1738 std::unique_lock<std::mutex> lock(mtx);
1739 cv.notify_all();
1740 }
1741 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1742 chrono::steady_clock::now() - startTime);
1743 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1744
1745 std::string stringOut = stdoutRecord.Stop();
1746 if (HasFailure()) {
1747 printf("output:\n%s", stringOut.c_str());
1748 }
1749 // some times 'sw-page-faults' is 0
1750 uint effectiveHeadCounter = 0u;
1751 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
1752 (defaultConfigNames_.size() - 1));
1753 t1.join();
1754 }
1755
1756 /**
1757 * @tc.name: TestOnSubCommand_p_t2
1758 * @tc.desc: -p -t
1759 * @tc.type: FUNC
1760 */
1761 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p_t2, TestSize.Level1)
1762 {
1763 StdoutRecord stdoutRecord;
1764 stdoutRecord.Start();
1765 const auto startTime = chrono::steady_clock::now();
1766
1767 std::string tidString = " -t ";
1768 tidString += "-1";
1769
1770 std::string cmdString = "stat";
1771 cmdString += tidString;
1772 cmdString += " -c 0 -d 3 --dumpoptions";
1773
1774 EXPECT_EQ(Command::DispatchCommand(cmdString), false);
1775 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1776 chrono::steady_clock::now() - startTime);
1777 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1778
1779 std::string stringOut = stdoutRecord.Stop();
1780 if (HasFailure()) {
1781 printf("output:\n%s", stringOut.c_str());
1782 }
1783
1784 std::string expectStr = "failed";
1785 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1786 }
1787
1788 /**
1789 * @tc.name: TestOnSubCommand_p_t3
1790 * @tc.desc: -p -t
1791 * @tc.type: FUNC
1792 */
1793 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p_t3, TestSize.Level1)
1794 {
1795 StdoutRecord stdoutRecord;
1796 stdoutRecord.Start();
1797 const auto startTime = chrono::steady_clock::now();
1798
1799 std::string tidString = " -t ";
1800 tidString += "test";
1801
1802 std::string cmdString = "stat";
1803 cmdString += tidString;
1804 cmdString += " -c 0 -d 3 --dumpoptions";
1805
1806 EXPECT_EQ(Command::DispatchCommand(cmdString), false);
1807 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1808 chrono::steady_clock::now() - startTime);
1809 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1810
1811 std::string stringOut = stdoutRecord.Stop();
1812 if (HasFailure()) {
1813 printf("output:\n%s", stringOut.c_str());
1814 }
1815
1816 std::string expectStr = "incorrect";
1817 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1818 }
1819
1820 /**
1821 * @tc.name: TestOnSubCommand_p_t4
1822 * @tc.desc: -p -t
1823 * @tc.type: FUNC
1824 */
1825 HWTEST_F(SubCommandStatTest, TestOnSubCommand_p_t4, TestSize.Level1)
1826 {
1827 int tid1 = 0;
1828 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1829
1830 printf("wait child thread run.\n");
1831 while (tid1 == 0) {
1832 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1833 }
1834
1835 StdoutRecord stdoutRecord;
1836 stdoutRecord.Start();
1837 const auto startTime = chrono::steady_clock::now();
1838
1839 std::string tidString = " -t ";
1840 tidString += std::to_string(tid1);
1841
1842 std::string cmdString = "stat";
1843 cmdString += tidString;
1844 cmdString += " -c 0 -d 3 --dumpoptions";
1845 g_wait = true;
1846 EXPECT_EQ(Command::DispatchCommand(cmdString), true);
1847 g_wait = false;
1848 {
1849 std::unique_lock<std::mutex> lock(mtx);
1850 cv.notify_all();
1851 }
1852 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1853 chrono::steady_clock::now() - startTime);
1854 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1855
1856 std::string stringOut = stdoutRecord.Stop();
1857 if (HasFailure()) {
1858 printf("output:\n%s", stringOut.c_str());
1859 }
1860 // some times 'sw-page-faults' is 0
1861 uint effectiveHeadCounter = 0u;
1862 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
1863 (defaultConfigNames_.size() - 1));
1864 t1.join();
1865 }
1866
1867 /**
1868 * @tc.name: TestOnSubCommand_verbose
1869 * @tc.desc: -p -t
1870 * @tc.type: FUNC
1871 */
1872 HWTEST_F(SubCommandStatTest, TestOnSubCommand_verbose, TestSize.Level1)
1873 {
1874 int tid1 = 0;
1875 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1876
1877 printf("wait child thread run.\n");
1878 while (tid1 == 0) {
1879 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1880 }
1881
1882 StdoutRecord stdoutRecord;
1883 stdoutRecord.Start();
1884 const auto startTime = chrono::steady_clock::now();
1885
1886 std::string tidString = " -t ";
1887 tidString += std::to_string(tid1);
1888
1889 std::string cmdString = "stat";
1890 cmdString += tidString;
1891 cmdString += " -c 0 -d 3 --verbose";
1892 g_wait = true;
1893 EXPECT_EQ(Command::DispatchCommand(cmdString), true);
1894 g_wait = false;
1895 {
1896 std::unique_lock<std::mutex> lock(mtx);
1897 cv.notify_all();
1898 }
1899 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1900 chrono::steady_clock::now() - startTime);
1901 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1902
1903 std::string stringOut = stdoutRecord.Stop();
1904 if (HasFailure()) {
1905 printf("output:\n%s", stringOut.c_str());
1906 }
1907
1908 std::string expectStr = "timeEnabled:";
1909 EXPECT_EQ(FindExpectStr(stringOut, expectStr), true);
1910 t1.join();
1911 }
1912
1913 /**
1914 * @tc.name: TestOnSubCommand_verbose1
1915 * @tc.desc: -p -t
1916 * @tc.type: FUNC
1917 */
1918 HWTEST_F(SubCommandStatTest, TestOnSubCommand_verbose1, TestSize.Level1)
1919 {
1920 int tid1 = 0;
1921 std::thread t1(SubCommandStatTest::TestCodeThread, std::ref(tid1));
1922
1923 printf("wait child thread run.\n");
1924 while (tid1 == 0) {
1925 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1926 }
1927
1928 StdoutRecord stdoutRecord;
1929 stdoutRecord.Start();
1930 const auto startTime = chrono::steady_clock::now();
1931
1932 std::string tidString = " -t ";
1933 tidString += std::to_string(tid1);
1934
1935 std::string cmdString = "stat";
1936 cmdString += tidString;
1937 cmdString += " -c 0 -d 3";
1938 g_wait = true;
1939 EXPECT_EQ(Command::DispatchCommand(cmdString), true);
1940 g_wait = false;
1941 {
1942 std::unique_lock<std::mutex> lock(mtx);
1943 cv.notify_all();
1944 }
1945 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1946 chrono::steady_clock::now() - startTime);
1947 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1948
1949 std::string stringOut = stdoutRecord.Stop();
1950 if (HasFailure()) {
1951 printf("output:\n%s", stringOut.c_str());
1952 }
1953
1954 std::string expectStr = "timeEnabled:";
1955 EXPECT_EQ(FindExpectStr(stringOut, expectStr), false);
1956 t1.join();
1957 }
1958
1959 /**
1960 * @tc.name: TestOnSubCommand_cmd
1961 * @tc.desc: hiperf stat <cmd>
1962 * @tc.type: FUNC
1963 */
1964 HWTEST_F(SubCommandStatTest, TestOnSubCommand_cmd, TestSize.Level1)
1965 {
1966 std::string cmdstr = "stat -c 0 -d 3 --dumpoptions ls -l";
1967
1968 StdoutRecord stdoutRecord;
1969 stdoutRecord.Start();
1970 const auto startTime = chrono::steady_clock::now();
1971 EXPECT_EQ(Command::DispatchCommand(cmdstr), true);
1972 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
1973 chrono::steady_clock::now() - startTime);
1974 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
1975
1976 std::string stringOut = stdoutRecord.Stop();
1977 if (HasFailure()) {
1978 printf("output:\n%s", stringOut.c_str());
1979 }
1980 // some times 'sw-page-faults' is 0
1981 uint effectiveHeadCounter = 0u;
1982 EXPECT_GE(EffectiveCounter(stringOut, defaultConfigNames_, effectiveHeadCounter),
1983 (defaultConfigNames_.size() - 1));
1984 }
1985
1986 /**
1987 * @tc.name: TestOnSubCommand_ni
1988 * @tc.desc: --no-inherit
1989 * @tc.type: FUNC
1990 */
1991 HWTEST_F(SubCommandStatTest, TestOnSubCommand_ni, TestSize.Level1)
1992 {
1993 StdoutRecord stdoutRecord;
1994 const std::string configName {"hw-cpu-cycles"};
1995
1996 stdoutRecord.Start();
1997 std::string testCMD = "stat --no-inherit -p 2 -c 0 -d 3 --dumpoptions -e ";
1998 testCMD += configName;
1999 const auto tick2 = std::chrono::steady_clock::now();
2000 EXPECT_EQ(Command::DispatchCommand(testCMD), true);
2001 const auto tock2 = std::chrono::steady_clock::now();
2002 const auto costMs2 = std::chrono::duration_cast<std::chrono::milliseconds>(tock2 - tick2);
2003 EXPECT_LE(costMs2.count(), defaultRunTimeoutMs);
2004 std::string stringOut = stdoutRecord.Stop();
2005 if (HasFailure()) {
2006 printf("output:\n%s", stringOut.c_str());
2007 }
2008 int counterValueWithoutInherit = CounterValue(stringOut, configName);
2009 EXPECT_NE(counterValueWithoutInherit, 0);
2010 HLOGD("%s %d", configName.c_str(), counterValueWithoutInherit);
2011 }
2012
2013 // ParseOption DumpOptions PrintUsage
2014 /**
2015 * @tc.name: TestParseOption_ni
2016 * @tc.desc: --no-inherit
2017 * @tc.type: FUNC
2018 */
2019 HWTEST_F(SubCommandStatTest, TestParseOption, TestSize.Level1)
2020 {
2021 SubCommandStat cmdStat;
2022 std::vector<std::string> args;
2023 args = {"-h"};
2024 EXPECT_EQ(cmdStat.ParseOption(args), true);
2025 args = {"-a"};
2026 EXPECT_EQ(cmdStat.ParseOption(args), true);
2027 args = {"-c"};
2028 EXPECT_EQ(cmdStat.ParseOption(args), false);
2029 args = {"-d"};
2030 EXPECT_EQ(cmdStat.ParseOption(args), false);
2031 args = {"-i"};
2032 EXPECT_EQ(cmdStat.ParseOption(args), false);
2033 args = {"-e"};
2034 EXPECT_EQ(cmdStat.ParseOption(args), false);
2035 args = {"-g"};
2036 EXPECT_EQ(cmdStat.ParseOption(args), false);
2037 args = {"--no-inherit"};
2038 EXPECT_EQ(cmdStat.ParseOption(args), true);
2039 args = {"-p"};
2040 EXPECT_EQ(cmdStat.ParseOption(args), false);
2041 args = {"-t"};
2042 EXPECT_EQ(cmdStat.ParseOption(args), false);
2043 args = {"--verbose"};
2044 EXPECT_EQ(cmdStat.ParseOption(args), true);
2045 args.clear();
2046 EXPECT_EQ(cmdStat.ParseOption(args), true);
2047 }
2048
2049 /**
2050 * @tc.name: TestDumpOptions
2051 * @tc.desc:
2052 * @tc.type: FUNC
2053 */
2054 HWTEST_F(SubCommandStatTest, TestDumpOptions, TestSize.Level1)
2055 {
2056 StdoutRecord stdoutRecord;
2057 stdoutRecord.Start();
2058 SubCommandStat cmdStat;
2059 cmdStat.DumpOptions();
2060 std::string stringOut = stdoutRecord.Stop();
2061 EXPECT_TRUE(stringOut.find("10000.000000 sec") != std::string::npos);
2062 }
2063
2064 /**
2065 * @tc.name: TestPrintUsage
2066 * @tc.desc:
2067 * @tc.type: FUNC
2068 */
2069 HWTEST_F(SubCommandStatTest, TestPrintUsage, TestSize.Level1)
2070 {
2071 StdoutRecord stdoutRecord;
2072 stdoutRecord.Start();
2073 SubCommandStat cmdStat;
2074 cmdStat.PrintUsage();
2075 std::string stringOut = stdoutRecord.Stop();
2076 EXPECT_TRUE(stringOut.find("Usage: hiperf stat [options] [command [command-args]]") !=
2077 std::string::npos);
2078 }
2079
2080 /**
2081 * @tc.name: TestCheckOptions
2082 * @tc.desc:
2083 * @tc.type: FUNC
2084 */
2085 HWTEST_F(SubCommandStatTest, TestCheckOptions, TestSize.Level1)
2086 {
2087 SubCommandStat cmdStat;
2088 std::vector<pid_t> pids;
2089
2090 cmdStat.timeStopSec_ = -1;
2091 EXPECT_EQ(cmdStat.CheckOptions(pids), false);
2092
2093 cmdStat.timeReportMs_ = -1;
2094 EXPECT_EQ(cmdStat.CheckOptions(pids), false);
2095
2096 cmdStat.targetSystemWide_ = true;
2097 pids = {1112, 1113};
2098 EXPECT_EQ(cmdStat.CheckOptions(pids), false);
2099
2100 cmdStat.trackedCommand_ = {"test"};
2101 EXPECT_EQ(cmdStat.CheckOptions(pids), false);
2102
2103 cmdStat.targetSystemWide_ = false;
2104 EXPECT_EQ(cmdStat.CheckOptions(pids), false);
2105 }
2106
2107 /**
2108 * @tc.name: TestReport
2109 * @tc.desc:
2110 * @tc.type: FUNC
2111 */
2112 HWTEST_F(SubCommandStatTest, TestReport, TestSize.Level1)
2113 {
2114 StdoutRecord stdoutRecord;
2115 stdoutRecord.Start();
2116 SubCommandStat cmdStat;
2117 std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> countEvents;
2118 std::unique_ptr<PerfEvents::CountEvent> testEvent(std::make_unique<PerfEvents::CountEvent>());
2119 std::string test = "test";
2120 countEvents[test] = std::move(testEvent);
2121 cmdStat.Report(countEvents);
2122 std::string stringOut = stdoutRecord.Stop();
2123 EXPECT_TRUE(stringOut.find("test") != std::string::npos);
2124 EXPECT_TRUE(stringOut.find("count name") != std::string::npos);
2125 }
2126
2127 /**
2128 * @tc.name: TestReport_Piling
2129 * @tc.desc:
2130 * @tc.type: FUNC
2131 */
2132 HWTEST_F(SubCommandStatTest, TestReport_Piling, TestSize.Level1)
2133 {
2134 SubCommandStat cmdStat;
2135 std::vector<std::string> eventNames = {
2136 "hw-branch-instructions", "hw-branch-misses", "hw-cpu-cycles", "hw-instructions",
2137 "sw-context-switches", "sw-page-faults", "sw-task-clock", "sw-cpu-migrations"};
2138 StdoutRecord stdoutRecord;
2139 stdoutRecord.Start();
2140 std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> countEvents;
2141 for (int i = 0; i < 8; i++) {
2142 auto countEvent = make_unique<PerfEvents::CountEvent>(PerfEvents::CountEvent {});
2143 std::string configName = eventNames[i];
2144 countEvents[configName] = std::move(countEvent);
2145 countEvents[configName]->userOnly = false;
2146 countEvents[configName]->kernelOnly = false;
2147 std::unique_ptr<PerfEvents::CountEvent> &countEventTmp = countEvents[configName];
2148 if (i == 0) {
2149 countEventTmp->eventCount = 20283000 * 10;
2150 } else if (i == 4) {
2151 countEventTmp->eventCount = 2028300;
2152 } else if (i == 5) {
2153 countEventTmp->eventCount = 2000;
2154 } else if (i == 7) {
2155 countEventTmp->eventCount = 20;
2156 } else {
2157 countEventTmp->eventCount = 20283000;
2158 }
2159 countEventTmp->timeEnabled = 2830280;
2160 countEventTmp->timeRunning = 2278140;
2161 countEventTmp->id = 0;
2162 countEventTmp->usedCpus = countEventTmp->eventCount / 1e9;
2163 }
2164 cmdStat.Report(countEvents);
2165 std::string stringOut = stdoutRecord.Stop();
2166 printf("output: %s\n", stringOut.c_str());
2167 EXPECT_EQ(FindExpectStr(stringOut, "G/sec"), true);
2168 EXPECT_EQ(FindExpectStr(stringOut, "M/sec"), true);
2169 EXPECT_EQ(FindExpectStr(stringOut, "K/sec"), true);
2170 EXPECT_EQ(FindExpectStr(stringOut, "/sec"), true);
2171 }
2172
2173 /**
2174 * @tc.name: HandleOtherConfig
2175 * @tc.desc: Test handle other config
2176 * @tc.type: FUNC
2177 */
2178 HWTEST_F(SubCommandStatTest, HandleOtherConfig, TestSize.Level1)
2179 {
2180 PerfEvents::Summary summary(1, 1, 1, 1, 1);
2181 double comment = 0;
2182 constexpr int testNum = 100;
2183 EXPECT_EQ(SubCommandStat::HandleOtherConfig(comment, summary, testNum, testNum, true), "");
2184 }
2185
2186 /**
2187 * @tc.name: CheckOptionPidAndApp
2188 * @tc.desc: Test handle other config
2189 * @tc.type: FUNC
2190 */
2191 HWTEST_F(SubCommandStatTest, CheckOptionPidAndApp, TestSize.Level1)
2192 {
2193 SubCommandStat stat;
2194 std::vector<pid_t> pids;
2195 EXPECT_EQ(stat.CheckOptionPidAndApp(pids), true);
2196 pids.push_back(1);
2197 pids.push_back(2); // 2: pid
2198 EXPECT_EQ(stat.CheckOptionPidAndApp(pids), true);
2199 pids.push_back(700011); // 700011: invalid pid
2200 EXPECT_EQ(stat.CheckOptionPidAndApp(pids), false);
2201 }
2202
2203 /**
2204 * @tc.name: TestOnSubCommand_restart_fail
2205 * @tc.desc: --restart
2206 * @tc.type: FUNC
2207 */
2208 HWTEST_F(SubCommandStatTest, TestOnSubCommand_restart_fail, TestSize.Level1)
2209 {
2210 StdoutRecord stdoutRecord;
2211 stdoutRecord.Start();
2212 const auto startTime = chrono::steady_clock::now();
2213 EXPECT_EQ(Command::DispatchCommand("stat --restart"), false);
2214 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
2215 chrono::steady_clock::now() - startTime);
2216 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
2217
2218 std::string stringOut = stdoutRecord.Stop();
2219 if (HasFailure()) {
2220 printf("output:\n%s", stringOut.c_str());
2221 }
2222 }
2223
2224 /**
2225 * @tc.name: TestOnSubCommand_app_running
2226 * @tc.desc: --app
2227 * @tc.type: FUNC
2228 */
2229 HWTEST_F(SubCommandStatTest, TestOnSubCommand_app_running, TestSize.Level1)
2230 {
2231 StdoutRecord stdoutRecord;
2232 stdoutRecord.Start();
2233 EXPECT_EQ(Command::DispatchCommand("stat --app com.app.notrunning -d 2"), false);
2234
2235 std::string stringOut = stdoutRecord.Stop();
2236 if (HasFailure()) {
2237 printf("output:\n%s", stringOut.c_str());
2238 }
2239 }
2240
2241 /**
2242 * @tc.name: CheckPidAndApp
2243 * @tc.desc: -p
2244 * @tc.type: FUNC
2245 */
2246 HWTEST_F(SubCommandStatTest, CheckPidAndApp, TestSize.Level1)
2247 {
2248 StdoutRecord stdoutRecord;
2249 stdoutRecord.Start();
2250 const auto startTime = chrono::steady_clock::now();
2251 EXPECT_EQ(Command::DispatchCommand("stat -p 700001 -d 2"), true);
2252 const auto costMs = std::chrono::duration_cast<std::chrono::milliseconds>(
2253 chrono::steady_clock::now() - startTime);
2254 EXPECT_LE(costMs.count(), defaultRunTimeoutMs);
2255
2256 std::string stringOut = stdoutRecord.Stop();
2257 if (HasFailure()) {
2258 printf("output:\n%s", stringOut.c_str());
2259 }
2260 }
2261 } // namespace HiPerf
2262 } // namespace Developtools
2263 } // namespace OHOS
2264