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