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