1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved. 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 <cinttypes> 17 #include <gtest/gtest.h> 18 #include <csignal> 19 #include <filesystem> 20 21 #include "ffrt_profiler_manager.h" 22 23 namespace fs = std::filesystem; 24 using namespace testing::ext; 25 using namespace OHOS::Developtools::Profiler; 26 27 namespace { 28 const std::string OUTPUT_PATH = "/data/local/tmp/hiprofiler_data.htrace"; 29 const std::string FFRT_TEST_EXE = "/data/local/tmp/ffrt_profiler_test_exe"; 30 constexpr int FILE_SIZE = 2000; 31 class FfrtPofilerTest : public ::testing::Test { 32 public: FfrtPofilerTest()33 FfrtPofilerTest() {} ~FfrtPofilerTest()34 ~FfrtPofilerTest() {} SetUpTestCase()35 static void SetUpTestCase() {} TearDownTestCase()36 static void TearDownTestCase() {} 37 CreateCommand(const std::string & outputFile,int32_t time,const std::string & model,const std::string & procedure) const38 std::string CreateCommand(const std::string& outputFile, int32_t time, const std::string& model, 39 const std::string& procedure) const 40 { 41 std::string cmdStr = 42 "hiprofiler_cmd \\\n" 43 "-c - \\\n"; 44 cmdStr += "-o " + outputFile + " \\\n"; 45 cmdStr += "-t " + std::to_string(time) + " \\\n"; 46 cmdStr += "-s \\\n"; 47 cmdStr += "-k \\\n" 48 "<<CONFIG\n" 49 "request_id: 1\n" 50 "session_config {\n" 51 " buffers {\n" 52 " pages: 32768\n" 53 " }\n" 54 " result_file: \"/data/local/tmp/hiprofiler_data.htrace\"\n" 55 " sample_duration: 30000\n" 56 "}\n" 57 "plugin_configs {\n" 58 " plugin_name: \"ffrt-profiler\"\n" 59 " config_data {\n"; 60 cmdStr += model + ": " + procedure + '\n'; 61 cmdStr += "smb_pages: 16384\n" 62 "flush_interval: 5\n" 63 "block: true\n" 64 "clock_id: BOOTTIME\n" 65 " }\n" 66 "}\n" 67 "CONFIG\n"; 68 return cmdStr; 69 } 70 StartProcess(const std::string & name,const std::string & args)71 void StartProcess(const std::string& name, const std::string& args) 72 { 73 if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) { 74 return; 75 } 76 77 int processNum = fork(); 78 if (processNum == 0) { 79 execl(name.c_str(), name.c_str(), args.c_str(), NULL); 80 _exit(1); 81 } else if (processNum < 0) { 82 PROFILER_LOG_ERROR(LOG_CORE, "Failed to fork process"); 83 } else { 84 PROFILER_LOG_ERROR(LOG_CORE, "sub process PID: %d", processNum); 85 ffrtPrfolerExePid_ = processNum; 86 } 87 } 88 RunCommand(const std::string & cmd,std::string & content)89 bool RunCommand(const std::string& cmd, std::string& content) 90 { 91 std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose); 92 CHECK_TRUE(pipe, false, "RunCommand: create popen FAILED!"); 93 static constexpr int buffSize = 1024; 94 std::array<char, buffSize> buffer; 95 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { 96 content += buffer.data(); 97 } 98 return true; 99 } 100 CheckFileSize(const std::string & filePath)101 bool CheckFileSize(const std::string& filePath) 102 { 103 if (!fs::exists(filePath)) { 104 return false; 105 } 106 if (fs::file_size(filePath) < FILE_SIZE) { 107 return false; 108 } 109 return true; 110 } 111 112 int ffrtPrfolerExePid_{0}; 113 }; 114 115 HWTEST_F(FfrtPofilerTest, TestFfrtProfilerRuntime, TestSize.Level1) 116 { 117 StartProcess(FFRT_TEST_EXE, "100"); 118 std::string cmd = CreateCommand(OUTPUT_PATH, 10, "pid", std::to_string(ffrtPrfolerExePid_)); 119 std::string ret; 120 fs::remove(OUTPUT_PATH); 121 EXPECT_TRUE(RunCommand(cmd, ret)); 122 EXPECT_TRUE(ret.find("FAIL") == std::string::npos); 123 } 124 125 HWTEST_F(FfrtPofilerTest, TestFfrtProfilerError, TestSize.Level1) 126 { 127 std::string cmd = CreateCommand(OUTPUT_PATH, 10, "pid", std::to_string(ffrtPrfolerExePid_)); 128 std::string ret; 129 fs::remove(OUTPUT_PATH); 130 EXPECT_TRUE(RunCommand(cmd, ret)); 131 EXPECT_TRUE(ret.find("FAIL") == std::string::npos); 132 EXPECT_FALSE(CheckFileSize(OUTPUT_PATH)); 133 } 134 }