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