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