1 /* 2 * Copyright (c) 2023-2025 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 #ifdef HAS_HIPERF 16 #include <iostream> 17 18 #include "file_util.h" 19 #include "perf_collector.h" 20 #include "string_util.h" 21 #include "time_util.h" 22 23 #include <gtest/gtest.h> 24 #include <thread> 25 26 using namespace testing::ext; 27 using namespace OHOS::HiviewDFX; 28 using namespace OHOS::HiviewDFX::UCollectUtil; 29 using namespace OHOS::HiviewDFX::UCollect; 30 31 constexpr char PERF_TEST_DIR[] = "/data/local/tmp/perf_test/"; 32 33 class PerfCollectorTest : public testing::Test { 34 public: SetUp()35 void SetUp() {}; TearDown()36 void TearDown() {}; 37 SetUpTestCase()38 static void SetUpTestCase() 39 { 40 FileUtil::ForceCreateDirectory(PERF_TEST_DIR); 41 }; 42 TearDownTestCase()43 static void TearDownTestCase() 44 { 45 FileUtil::ForceRemoveDirectory(PERF_TEST_DIR); 46 }; 47 }; 48 49 /** 50 * @tc.name: PerfCollectorTest001 51 * @tc.desc: used to test PerfCollector.StartPerf 52 * @tc.type: FUNC 53 */ 54 HWTEST_F(PerfCollectorTest, PerfCollectorTest001, TestSize.Level1) 55 { 56 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::EVENTLOGGER); 57 vector<pid_t> selectPids = {getpid()}; 58 std::string filename = "hiperf-"; 59 filename += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC, 60 "%Y%m%d%H%M%S"); 61 filename += ".data"; 62 perfCollector->SetOutputFilename(filename); 63 perfCollector->SetSelectPids(selectPids); 64 perfCollector->SetTimeStopSec(3); 65 CollectResult<bool> data = perfCollector->StartPerf(PERF_TEST_DIR); 66 std::cout << "collect perf data result" << data.retCode << std::endl; 67 ASSERT_TRUE(data.retCode == UcError::SUCCESS); 68 } 69 70 /** 71 * @tc.name: PerfCollectorTest002 72 * @tc.desc: used to test PerfCollector.StartPerf 73 * @tc.type: FUNC 74 */ 75 HWTEST_F(PerfCollectorTest, PerfCollectorTest002, TestSize.Level1) 76 { 77 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::XPOWER); 78 vector<pid_t> selectPids = {getpid()}; 79 std::string filename = "hiperf-"; 80 filename += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC, 81 "%Y%m%d%H%M%S"); 82 filename += ".data"; 83 std::string filepath = PERF_TEST_DIR + filename; 84 perfCollector->SetOutputFilename(filename); 85 perfCollector->SetSelectPids(selectPids); 86 perfCollector->SetTimeStopSec(3); 87 CollectResult<bool> data = perfCollector->StartPerf(PERF_TEST_DIR); 88 std::cout << "collect perf data result" << data.retCode << std::endl; 89 ASSERT_EQ(FileUtil::FileExists(filepath), true); 90 } 91 92 /** 93 * @tc.name: PerfCollectorTest003 94 * @tc.desc: used to test PerfCollector.SetTargetSystemWide 95 * @tc.type: FUNC 96 */ 97 HWTEST_F(PerfCollectorTest, PerfCollectorTest003, TestSize.Level1) 98 { 99 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::UNIFIED_COLLECTOR); 100 vector<pid_t> selectPids = {getpid()}; 101 std::string filename = "hiperf-"; 102 filename += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC, 103 "%Y%m%d%H%M%S"); 104 filename += ".data"; 105 std::string filepath = PERF_TEST_DIR + filename; 106 perfCollector->SetOutputFilename(filename); 107 perfCollector->SetTargetSystemWide(true); 108 perfCollector->SetCallGraph("fp"); 109 std::vector<std::string> selectEvents = {"hw-cpu-cycles", "hw-instructions"}; 110 perfCollector->SetSelectEvents(selectEvents); 111 CollectResult<bool> data = perfCollector->Prepare(PERF_TEST_DIR); 112 ASSERT_TRUE(data.retCode == UcError::SUCCESS); 113 TimeUtil::Sleep(1); 114 data = perfCollector->StartRun(); 115 ASSERT_TRUE(data.retCode == UcError::SUCCESS); 116 TimeUtil::Sleep(1); 117 data = perfCollector->Stop(); 118 ASSERT_TRUE(data.retCode == UcError::SUCCESS); 119 std::cout << "collect perf data result" << data.retCode << std::endl; 120 ASSERT_EQ(FileUtil::FileExists(filepath), true); 121 } 122 123 /** 124 * @tc.name: PerfCollectorTest004 125 * @tc.desc: used to test PerfCollector.SetCpuPercent 126 * @tc.type: FUNC 127 */ 128 HWTEST_F(PerfCollectorTest, PerfCollectorTest004, TestSize.Level1) 129 { 130 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::PERFORMANCE_FACTORY); 131 vector<pid_t> selectPids = {getpid()}; 132 std::string filename = "hiperf-"; 133 filename += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC, 134 "%Y%m%d%H%M%S"); 135 filename += ".data"; 136 std::string filepath = PERF_TEST_DIR + filename; 137 perfCollector->SetOutputFilename(filename); 138 perfCollector->SetSelectPids(selectPids); 139 perfCollector->SetFrequency(100); 140 perfCollector->SetTimeStopSec(2); 141 perfCollector->SetCpuPercent(100); 142 CollectResult<bool> data = perfCollector->StartPerf(PERF_TEST_DIR); 143 std::cout << "collect perf data result" << data.retCode << std::endl; 144 ASSERT_EQ(FileUtil::FileExists(filepath), true); 145 } 146 147 /** 148 * @tc.name: PerfCollectorTest005 149 * @tc.desc: used to test PerfCollector.SetReport 150 * @tc.type: FUNC 151 */ 152 HWTEST_F(PerfCollectorTest, PerfCollectorTest005, TestSize.Level1) 153 { 154 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::PERFORMANCE_FACTORY); 155 vector<pid_t> selectPids = {getpid()}; 156 std::string filename = "hiperf-"; 157 filename += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC, 158 "%Y%m%d%H%M%S"); 159 filename += ".data"; 160 std::string filepath = PERF_TEST_DIR + filename; 161 perfCollector->SetOutputFilename(filename); 162 perfCollector->SetSelectPids(selectPids); 163 perfCollector->SetTimeStopSec(3); 164 perfCollector->SetReport(true); 165 CollectResult<bool> data = perfCollector->StartPerf(PERF_TEST_DIR); 166 std::cout << "collect perf data result" << data.retCode << std::endl; 167 ASSERT_EQ(FileUtil::FileExists(filepath), true); 168 } 169 170 /** 171 * @tc.name: PerfCollectorTest006 172 * @tc.desc: used to test concurrent control for perf collection 173 * @tc.type: FUNC 174 */ 175 HWTEST_F(PerfCollectorTest, PerfCollectorTest006, TestSize.Level1) 176 { 177 vector<pid_t> selectPids = {getpid()}; 178 std::string fileDir = PERF_TEST_DIR; 179 for (int index = 0; index < 5; ++index) { // 5 : start 5 threads to collect perf data 180 std::string fileName = "concurrency-hiperf-" + std::to_string(index) + ".data"; __anonc89d554f0102() 181 std::thread([fileDir, fileName, selectPids]() { 182 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::EVENTLOGGER); 183 perfCollector->SetOutputFilename(fileName); 184 perfCollector->SetSelectPids(selectPids); 185 perfCollector->SetTimeStopSec(3); // 3 : perf collection will stop after this time 186 CollectResult<bool> data = perfCollector->StartPerf(fileDir); 187 }).detach(); 188 } 189 sleep(5); // 5 : wati 5 seconds to ensure perf collection is completed 190 std::vector<std::string> files; 191 FileUtil::GetDirFiles(PERF_TEST_DIR, files, false); 192 int perfDataCount = 0; 193 for (const auto& file : files) { 194 if (StringUtil::StartWith(FileUtil::ExtractFileName(file), "concurrency")) { 195 ++perfDataCount; 196 } 197 } 198 ASSERT_EQ(perfDataCount, 2); // 2 : max perf count for eventlogger simultaneously 199 } 200 #endif // HAS_HIPERF 201