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 #include <iostream> 16 17 #include "file_util.h" 18 #include "parameter_ex.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 #ifdef HAS_HIPERF 50 /** 51 * @tc.name: PerfCollectorTest001 52 * @tc.desc: used to test PerfCollector.StartPerf 53 * @tc.type: FUNC 54 */ 55 HWTEST_F(PerfCollectorTest, PerfCollectorTest001, TestSize.Level1) 56 { 57 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::EVENTLOGGER); 58 vector<pid_t> selectPids = {getpid()}; 59 std::string filename = "hiperf-"; 60 filename += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC, 61 "%Y%m%d%H%M%S"); 62 filename += ".data"; 63 perfCollector->SetOutputFilename(filename); 64 perfCollector->SetSelectPids(selectPids); 65 perfCollector->SetTimeStopSec(3); 66 CollectResult<bool> data = perfCollector->StartPerf(PERF_TEST_DIR); 67 std::cout << "collect perf data result" << data.retCode << std::endl; 68 ASSERT_TRUE(data.retCode == UcError::SUCCESS); 69 } 70 71 /** 72 * @tc.name: PerfCollectorTest002 73 * @tc.desc: used to test PerfCollector.StartPerf 74 * @tc.type: FUNC 75 */ 76 HWTEST_F(PerfCollectorTest, PerfCollectorTest002, TestSize.Level1) 77 { 78 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::XPOWER); 79 vector<pid_t> selectPids = {getpid()}; 80 std::string filename = "hiperf-"; 81 filename += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC, 82 "%Y%m%d%H%M%S"); 83 filename += ".data"; 84 std::string filepath = PERF_TEST_DIR + filename; 85 perfCollector->SetOutputFilename(filename); 86 perfCollector->SetSelectPids(selectPids); 87 perfCollector->SetTimeStopSec(3); 88 CollectResult<bool> data = perfCollector->StartPerf(PERF_TEST_DIR); 89 std::cout << "collect perf data result" << data.retCode << std::endl; 90 ASSERT_EQ(FileUtil::FileExists(filepath), true); 91 } 92 93 /** 94 * @tc.name: PerfCollectorTest003 95 * @tc.desc: used to test PerfCollector.SetTargetSystemWide 96 * @tc.type: FUNC 97 */ 98 HWTEST_F(PerfCollectorTest, PerfCollectorTest003, TestSize.Level1) 99 { 100 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::UNIFIED_COLLECTOR); 101 vector<pid_t> selectPids = {getpid()}; 102 std::string filename = "hiperf-"; 103 filename += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC, 104 "%Y%m%d%H%M%S"); 105 filename += ".data"; 106 std::string filepath = PERF_TEST_DIR + filename; 107 perfCollector->SetOutputFilename(filename); 108 perfCollector->SetTargetSystemWide(true); 109 perfCollector->SetCallGraph("fp"); 110 std::vector<std::string> selectEvents = {"hw-cpu-cycles", "hw-instructions"}; 111 perfCollector->SetSelectEvents(selectEvents); 112 CollectResult<bool> data = perfCollector->Prepare(PERF_TEST_DIR); 113 ASSERT_TRUE(data.retCode == UcError::SUCCESS); 114 TimeUtil::Sleep(1); 115 data = perfCollector->StartRun(); 116 ASSERT_TRUE(data.retCode == UcError::SUCCESS); 117 TimeUtil::Sleep(1); 118 data = perfCollector->Stop(); 119 ASSERT_TRUE(data.retCode == UcError::SUCCESS); 120 std::cout << "collect perf data result" << data.retCode << std::endl; 121 ASSERT_EQ(FileUtil::FileExists(filepath), true); 122 } 123 124 /** 125 * @tc.name: PerfCollectorTest004 126 * @tc.desc: used to test PerfCollector.SetCpuPercent 127 * @tc.type: FUNC 128 */ 129 HWTEST_F(PerfCollectorTest, PerfCollectorTest004, TestSize.Level1) 130 { 131 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::PERFORMANCE_FACTORY); 132 vector<pid_t> selectPids = {getpid()}; 133 std::string filename = "hiperf-"; 134 filename += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC, 135 "%Y%m%d%H%M%S"); 136 filename += ".data"; 137 std::string filepath = PERF_TEST_DIR + filename; 138 perfCollector->SetOutputFilename(filename); 139 perfCollector->SetSelectPids(selectPids); 140 perfCollector->SetFrequency(100); 141 perfCollector->SetTimeStopSec(2); 142 perfCollector->SetCpuPercent(100); 143 CollectResult<bool> data = perfCollector->StartPerf(PERF_TEST_DIR); 144 std::cout << "collect perf data result" << data.retCode << std::endl; 145 ASSERT_EQ(FileUtil::FileExists(filepath), true); 146 } 147 148 /** 149 * @tc.name: PerfCollectorTest005 150 * @tc.desc: used to test PerfCollector.SetReport 151 * @tc.type: FUNC 152 */ 153 HWTEST_F(PerfCollectorTest, PerfCollectorTest005, TestSize.Level1) 154 { 155 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::PERFORMANCE_FACTORY); 156 vector<pid_t> selectPids = {getpid()}; 157 std::string filename = "hiperf-"; 158 filename += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC, 159 "%Y%m%d%H%M%S"); 160 filename += ".data"; 161 std::string filepath = PERF_TEST_DIR + filename; 162 perfCollector->SetOutputFilename(filename); 163 perfCollector->SetSelectPids(selectPids); 164 perfCollector->SetTimeStopSec(3); 165 perfCollector->SetReport(true); 166 CollectResult<bool> data = perfCollector->StartPerf(PERF_TEST_DIR); 167 std::cout << "collect perf data result" << data.retCode << std::endl; 168 ASSERT_EQ(FileUtil::FileExists(filepath), true); 169 } 170 171 /** 172 * @tc.name: PerfCollectorTest006 173 * @tc.desc: used to test concurrent control for perf collection 174 * @tc.type: FUNC 175 */ 176 HWTEST_F(PerfCollectorTest, PerfCollectorTest006, TestSize.Level1) 177 { 178 vector<pid_t> selectPids = {getpid()}; 179 std::string fileDir = PERF_TEST_DIR; 180 for (int index = 0; index < 5; ++index) { // 5 : start 5 threads to collect perf data 181 std::string fileName = "concurrency-hiperf-" + std::to_string(index) + ".data"; __anon5951482f0102() 182 std::thread([fileDir, fileName, selectPids]() { 183 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::EVENTLOGGER); 184 perfCollector->SetOutputFilename(fileName); 185 perfCollector->SetSelectPids(selectPids); 186 perfCollector->SetTimeStopSec(3); // 3 : perf collection will stop after this time 187 CollectResult<bool> data = perfCollector->StartPerf(fileDir); 188 }).detach(); 189 } 190 sleep(5); // 5 : wati 5 seconds to ensure perf collection is completed 191 std::vector<std::string> files; 192 FileUtil::GetDirFiles(PERF_TEST_DIR, files, false); 193 int perfDataCount = 0; 194 for (const auto& file : files) { 195 if (StringUtil::StartWith(FileUtil::ExtractFileName(file), "concurrency")) { 196 ++perfDataCount; 197 } 198 } 199 ASSERT_EQ(perfDataCount, 2); // 2 : max perf count for eventlogger simultaneously 200 } 201 202 /** 203 * @tc.name: PerfCollectorTest007 204 * @tc.desc: used to test invalid caller for perf collect 205 * @tc.type: FUNC 206 */ 207 HWTEST_F(PerfCollectorTest, PerfCollectorTest007, TestSize.Level1) 208 { 209 const int invalidNum = 100; // 100 : invalid number used to cast to PerfCaller 210 auto perfCollector = UCollectUtil::PerfCollector::Create(static_cast<PerfCaller>(invalidNum)); 211 vector<pid_t> selectPids = {getpid()}; 212 std::string filename = "hiperf-"; 213 filename += TimeUtil::TimestampFormatToDate(TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC, 214 "%Y%m%d%H%M%S"); 215 filename += ".data"; 216 std::string filepath = PERF_TEST_DIR + filename; 217 perfCollector->SetOutputFilename(filename); 218 perfCollector->SetSelectPids(selectPids); 219 perfCollector->SetTimeStopSec(3); 220 perfCollector->SetReport(true); 221 CollectResult<bool> data = perfCollector->StartPerf(PERF_TEST_DIR); 222 std::cout << "collect perf data result" << data.retCode << std::endl; 223 ASSERT_EQ(data.retCode, UcError::PERF_CALLER_NOT_FIND); 224 data = perfCollector->Prepare(PERF_TEST_DIR); 225 ASSERT_EQ(data.retCode, UcError::PERF_CALLER_NOT_FIND); 226 } 227 228 #else 229 /** 230 * @tc.name: PerfCollectorTest001 231 * @tc.desc: used to test empty PerfCollector 232 * @tc.type: FUNC 233 */ 234 HWTEST_F(PerfCollectorTest, PerfCollectorTest001, TestSize.Level1) 235 { 236 auto perfCollector = UCollectUtil::PerfCollector::Create(PerfCaller::PERFORMANCE_FACTORY); 237 perfCollector->SetSelectPids({}); 238 perfCollector->SetTargetSystemWide(true); 239 perfCollector->SetTimeStopSec(0); 240 perfCollector->SetFrequency(0); 241 perfCollector->SetOffCPU(true); 242 perfCollector->SetOutputFilename(""); 243 perfCollector->SetCallGraph(""); 244 perfCollector->SetSelectEvents({}); 245 perfCollector->SetCpuPercent(0); 246 perfCollector->SetCpuPercent(true); 247 248 CollectResult<bool> data = perfCollector->StartPerf(""); 249 ASSERT_TRUE(data.retCode == UcError::FEATURE_CLOSED); 250 data = perfCollector->Prepare(""); 251 ASSERT_TRUE(data.retCode == UcError::FEATURE_CLOSED); 252 data = perfCollector->StartRun(); 253 ASSERT_TRUE(data.retCode == UcError::FEATURE_CLOSED); 254 data = perfCollector->Pause(); 255 ASSERT_TRUE(data.retCode == UcError::FEATURE_CLOSED); 256 data = perfCollector->Resume(); 257 ASSERT_TRUE(data.retCode == UcError::FEATURE_CLOSED); 258 data = perfCollector->Stop(); 259 ASSERT_TRUE(data.retCode == UcError::FEATURE_CLOSED); 260 } 261 #endif // HAS_HIPERF 262 263