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