1 /* 2 * Copyright (c) 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 16 #include <fstream> 17 #include <sstream> 18 #include <set> 19 #include "perf_test.h" 20 #include "ipc_skeleton.h" 21 22 namespace OHOS::perftest { 23 using namespace std; 24 GetPidByBundleName(string bundleName)25 int32_t PerfTest::GetPidByBundleName(string bundleName) 26 { 27 string getPidCmd = "pidof " + bundleName; 28 int32_t pid = -1; 29 FILE *fp = popen(getPidCmd.c_str(), "r"); 30 if (fp == nullptr) { 31 LOG_E("Excute popen to get process pid failed"); 32 return pid; 33 } 34 string pidStr; 35 char bufferInfo[1024] = { '\0' }; 36 while (fgets(bufferInfo, sizeof(bufferInfo), fp) != nullptr) { 37 pidStr += bufferInfo; 38 } 39 pclose(fp); 40 LOG_I("Pid of process %{public}s is %{public}s", bundleName.c_str(), pidStr.c_str()); 41 stringstream pidStream(pidStr); 42 pidStream >> pid; 43 return pid; 44 } 45 RunTest(ApiCallErr & error)46 void PerfTest::RunTest(ApiCallErr &error) 47 { 48 LOG_I("%{public}s called", __func__); 49 auto bundleName = perfTestStrategy_->GetBundleName(); 50 auto dataCollections = perfTestStrategy_->GetDataCollections(); 51 for (auto dataCollection : dataCollections) { 52 dataCollection.second->SetBundleName(bundleName); 53 } 54 isMeasureRunning_ = true; 55 measureResult_.clear(); 56 for (int32_t iteration = 0; iteration < perfTestStrategy_->GetIterations(); iteration++) { 57 for (auto& dataCollection : dataCollections) { 58 dataCollection.second->StartCollection(error); 59 if (error.code_ != NO_ERROR) { 60 isMeasureRunning_ = false; 61 return; 62 } 63 } 64 perfTestCallback_->OnCall(perfTestStrategy_->GetActionCodeRef(), perfTestStrategy_->GetTimeout(), error); 65 if (error.code_ != NO_ERROR) { 66 LOG_E("ActionCode call error"); 67 isMeasureRunning_ = false; 68 return; 69 } 70 for (auto& dataCollection : dataCollections) { 71 double res = dataCollection.second->StopCollectionAndGetResult(error); 72 if (error.code_ != NO_ERROR) { 73 isMeasureRunning_ = false; 74 return; 75 } 76 measureResult_[dataCollection.first].push_back(res); 77 } 78 perfTestCallback_->OnCall(perfTestStrategy_->GetResetCodeRef(), perfTestStrategy_->GetTimeout(), error); 79 if (error.code_ != NO_ERROR) { 80 LOG_E("ResetCode call error"); 81 isMeasureRunning_ = false; 82 return; 83 } 84 } 85 isMeasureRunning_ = false; 86 isMeasureComplete_ = true; 87 } 88 GetMeasureResult(PerfMetric perfMetric,ApiCallErr & error)89 nlohmann::json PerfTest::GetMeasureResult(PerfMetric perfMetric, ApiCallErr &error) 90 { 91 LOG_I("%{public}s called", __func__); 92 nlohmann::json resData; 93 if (perfTestStrategy_->GetPerfMetrics().count(perfMetric) == ZERO) { 94 error = ApiCallErr(ERR_INVALID_INPUT, "PerfMetric: " + to_string(perfMetric) + " is not set to measure"); 95 return resData; 96 } 97 if (!isMeasureComplete_ || measureResult_.count(perfMetric) == ZERO || 98 measureResult_[perfMetric].size() != perfTestStrategy_->GetIterations()) { 99 error = ApiCallErr(ERR_GET_RESULT_FAILED, 100 "PerfMetric: " + to_string(perfMetric) + " has not been measured yet"); 101 return resData; 102 } 103 list<double> resList = measureResult_[perfMetric]; 104 list<double> validResList; 105 for (auto res : resList) { 106 if (res > INVALID_VALUE) { 107 validResList.push_back(res); 108 } 109 } 110 resData["metric"] = perfMetric; 111 resData["roundValues"] = resList; 112 if (validResList.empty()) { 113 resData["maximum"] = INITIAL_VALUE; 114 resData["minimum"] = INITIAL_VALUE; 115 resData["average"] = INITIAL_VALUE; 116 } else { 117 resData["maximum"] = *max_element(validResList.begin(), validResList.end()); 118 resData["minimum"] = *min_element(validResList.begin(), validResList.end()); 119 resData["average"] = accumulate(validResList.begin(), validResList.end(), 0.0) / validResList.size(); 120 } 121 return resData; 122 } 123 IsMeasureRunning()124 bool PerfTest::IsMeasureRunning() 125 { 126 return isMeasureRunning_; 127 } 128 Destroy(ApiCallErr & error)129 void PerfTest::Destroy(ApiCallErr &error) 130 { 131 list<string> codeRefs; 132 codeRefs.push_back(perfTestStrategy_->GetActionCodeRef()); 133 if (!perfTestStrategy_->GetResetCodeRef().empty()) { 134 codeRefs.push_back(perfTestStrategy_->GetResetCodeRef()); 135 } 136 perfTestCallback_->OnDestroy(codeRefs, error); 137 } 138 } // namespace OHOS::perftest 139