• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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