From cbce66872cafda051502012fc109146993e855dc Mon Sep 17 00:00:00 2001 From: buzhenwang Date: Fri, 29 Aug 2025 14:04:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DUT=E6=B5=8B=E8=AF=95=E7=94=A8?= =?UTF-8?q?=E5=8A=9B=E6=A6=82=E7=8E=87=E6=80=A7=E5=A4=B1=E8=B4=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20Signed-off-by:leiguangyu=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: buzhenwang --- demo/cpp/hiperf_demo.cpp | 6 +- test/BUILD.gn | 9 ++ .../unittest/common/native/cpu_usage_test.cpp | 21 ++- .../common/native/hiperf_client_test.cpp | 17 ++- .../common/native/hiperf_test_demo.cpp | 98 ++++++++++++++ .../common/native/spe_decoder_test.cpp | 18 +-- .../common/native/subcommand_record_test.cpp | 121 ++++++++++++++---- .../common/native/subcommand_stat_test.cpp | 17 ++- .../unittest/common/native/utilities_test.cpp | 17 ++- test/unittest/resource/ohos_test.xml | 1 + 10 files changed, 250 insertions(+), 75 deletions(-) create mode 100644 test/unittest/common/native/hiperf_test_demo.cpp diff --git a/demo/cpp/hiperf_demo.cpp b/demo/cpp/hiperf_demo.cpp index eed836f..f7aa642 100644 --- a/demo/cpp/hiperf_demo.cpp +++ b/demo/cpp/hiperf_demo.cpp @@ -20,11 +20,7 @@ using namespace OHOS::Developtools::HiPerf; -#if defined(__aarch64__) -static const std::string TEST_PROCESSES = "com.ohos.launcher"; -#else -static const std::string TEST_PROCESSES = "hiview"; -#endif +static const std::string TEST_PROCESSES = "hiperf_test_demo"; namespace HiperfClientDemo { void TestCodeThread(int id) diff --git a/test/BUILD.gn b/test/BUILD.gn index aabe9d0..e42c72b 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -95,11 +95,20 @@ config("hiperf_test_config") { include_dirs = [ "${hiperf_path}/test/unittest/common/native/include" ] } + +ohos_executable("hiperf_test_demo") { + cflags = [ "-O0" ] + sources = [ "unittest/common/native/hiperf_test_demo.cpp" ] + subsystem_name = "developtools" + part_name = "hiperf" +} + ohos_unittest("hiperf_unittest") { configs = [ ":hiperf_test_config" ] module_out_path = module_output_path resource_config_file = "unittest/resource/ohos_test.xml" deps = [ + ":hiperf_test_demo", "${hiperf_path}/interfaces/innerkits/native/hiperf_client:hiperf_client_static", "${hiperf_path}/interfaces/innerkits/native/hiperf_local:hiperf_local", ] diff --git a/test/unittest/common/native/cpu_usage_test.cpp b/test/unittest/common/native/cpu_usage_test.cpp index 74717e1..ef7fd6b 100644 --- a/test/unittest/common/native/cpu_usage_test.cpp +++ b/test/unittest/common/native/cpu_usage_test.cpp @@ -42,21 +42,21 @@ public: float GetAverageCpuUsage(pid_t pid, uint64_t timeOut); void TestCpuUsage(const std::string &option, unsigned int expect, bool fixPid); - - std::string testProcesses = "com.ohos.launcher"; }; -void CpuUsageTest::SetUpTestCase() {} - -void CpuUsageTest::TearDownTestCase() {} +void CpuUsageTest::SetUpTestCase() +{ + chmod("/data/test/hiperf_test_demo", 0755); // 0755 : -rwxr-xr-x + system("/data/test/hiperf_test_demo &"); +} -void CpuUsageTest::SetUp() +void CpuUsageTest::TearDownTestCase() { - if (!HiPerf::CheckTestApp(testProcesses)) { - testProcesses = "hiview"; - } + system("kill -9 `pidof hiperf_test_demo`"); } +void CpuUsageTest::SetUp() {} + void CpuUsageTest::TearDown() {} pid_t CpuUsageTest::GetPidByProcessName(const std::string& procName) @@ -221,8 +221,7 @@ void CpuUsageTest::TestCpuUsage(const std::string &option, unsigned int expect, { std::string cmd = "hiperf record "; if (fixPid) { - cmd += "--app "; - cmd += " " + testProcesses; + cmd += "--app hiperf_test_demo"; } cmd += " " + option; diff --git a/test/unittest/common/native/hiperf_client_test.cpp b/test/unittest/common/native/hiperf_client_test.cpp index 0958866..b89cfe8 100644 --- a/test/unittest/common/native/hiperf_client_test.cpp +++ b/test/unittest/common/native/hiperf_client_test.cpp @@ -39,18 +39,21 @@ public: static void TestCaseOption(const HiperfClient::RecordOption &opt); }; -void HiperfClientTest::SetUpTestCase() {} +void HiperfClientTest::SetUpTestCase() +{ + chmod("/data/test/hiperf_test_demo", 0755); // 0755 : -rwxr-xr-x + system("/data/test/hiperf_test_demo &"); +} void HiperfClientTest::TearDownTestCase() { DebugLogger::GetInstance()->Reset(); + system("kill -9 `pidof hiperf_test_demo`"); } void HiperfClientTest::SetUp() {} -void HiperfClientTest::TearDown() -{ -} +void HiperfClientTest::TearDown() {} /** * @tc.name: @@ -426,11 +429,7 @@ HWTEST_F(HiperfClientTest, SetDataLimit, TestSize.Level2) HWTEST_F(HiperfClientTest, SetAppPackage, TestSize.Level0) { HiperfClient::RecordOption opt; - std::string testProcesses = "com.ohos.launcher"; - if (!CheckTestApp(testProcesses)) { - testProcesses = "hiview"; - } - opt.SetAppPackage(testProcesses); + opt.SetAppPackage("hiperf_test_demo"); TestCaseOption(opt); } diff --git a/test/unittest/common/native/hiperf_test_demo.cpp b/test/unittest/common/native/hiperf_test_demo.cpp new file mode 100644 index 0000000..cf5551b --- /dev/null +++ b/test/unittest/common/native/hiperf_test_demo.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +const int WAITTIME = 200000; +const int BUFSIZE = 1048576; + +void Func10() +{ + void *temp = nullptr; + // try for each thread times + while (true) { + temp = malloc(BUFSIZE); + usleep(WAITTIME); + if (temp != nullptr) { + free(temp); + temp = nullptr; + } + } +} + +void Func9() +{ + Func10(); +} + +void Func8() +{ + Func9(); +} + +void Func7() +{ + Func8(); +} + +void Func6() +{ + Func7(); +} + +void Func5() +{ + Func6(); +} + +void Func4() +{ + Func5(); +} + +void Func3() +{ + Func4(); +} + +void Func2() +{ + Func3(); +} + +void Func1() +{ + Func2(); +} + +void ThreadFunction() +{ + Func1(); +} + +int main(const int argc, const char *argv[]) +{ + std::vector threads; + for (int i = 0; i < 10; ++i) { // 10: create 10 threads + threads.push_back(std::thread(ThreadFunction)); + usleep(WAITTIME); + } + for (auto& th : threads) { + th.join(); + } + return 0; +}; diff --git a/test/unittest/common/native/spe_decoder_test.cpp b/test/unittest/common/native/spe_decoder_test.cpp index 4cdf976..001f4f2 100644 --- a/test/unittest/common/native/spe_decoder_test.cpp +++ b/test/unittest/common/native/spe_decoder_test.cpp @@ -33,9 +33,16 @@ public: void TearDown(); }; -void SpeDecoderTest::SetUpTestCase() {} +void SpeDecoderTest::SetUpTestCase() +{ + chmod("/data/test/hiperf_test_demo", 0755); // 0755 : -rwxr-xr-x + system("/data/test/hiperf_test_demo &"); +} -void SpeDecoderTest::TearDownTestCase() {} +void SpeDecoderTest::TearDownTestCase() +{ + system("kill -9 `pidof hiperf_test_demo`"); +} void SpeDecoderTest::SetUp() { @@ -94,12 +101,7 @@ HWTEST_F(SpeDecoderTest, TestGetSpeEventNameByType, TestSize.Level1) HWTEST_F(SpeDecoderTest, TestRecord, TestSize.Level0) { StdoutRecord stdoutRecord; - std::string testProcesses = "com.ohos.launcher"; - if (!CheckTestApp(testProcesses)) { - testProcesses = "hiview"; - } - std::string cmdString = "record -e arm_spe_0/load_filter=1,min_latency=100/ -d 10 --app "; - cmdString += " " + testProcesses; + std::string cmdString = "record -e arm_spe_0/load_filter=1,min_latency=100/ -d 10 --app hiperf_test_demo"; printf("command : %s\n", cmdString.c_str()); // it need load some symbols and much more log stdoutRecord.Start(); diff --git a/test/unittest/common/native/subcommand_record_test.cpp b/test/unittest/common/native/subcommand_record_test.cpp index 32f6c87..2dbed38 100644 --- a/test/unittest/common/native/subcommand_record_test.cpp +++ b/test/unittest/common/native/subcommand_record_test.cpp @@ -69,17 +69,21 @@ public: static std::string testProcesses; }; -std::string SubCommandRecordTest::testProcesses = "com.ohos.launcher"; +std::string SubCommandRecordTest::testProcesses = "hiperf_test_demo"; -void SubCommandRecordTest::SetUpTestCase() {} +void SubCommandRecordTest::SetUpTestCase() +{ + chmod("/data/test/hiperf_test_demo", 0755); // 0755 : -rwxr-xr-x + system("/data/test/hiperf_test_demo &"); +} -void SubCommandRecordTest::TearDownTestCase() {} +void SubCommandRecordTest::TearDownTestCase() +{ + system("kill -9 `pidof hiperf_test_demo`"); +} void SubCommandRecordTest::SetUp() { - if (!CheckTestApp(SubCommandRecordTest::testProcesses)) { - SubCommandRecordTest::testProcesses = "hiview"; - } SubCommand::ClearSubCommands(); // clear the subCommands left from other UT ASSERT_EQ(SubCommand::GetSubCommands().size(), 0u); SubCommand::RegisterSubCommand("record", std::make_unique()); @@ -212,27 +216,49 @@ static bool CheckIntFromProcFile(const std::string& proc, int expect) return value == expect; } -bool CheckJsonReport(const std::string& fileName, const std::string& symbolsFile, const int index = 0) +static int g_maxCallstack = 0; +void CheckLevel(cJSON* list, int level) { - cJSON* root = ParseJson(fileName.c_str()); - if (root == nullptr) { - return false; + if (list == nullptr) { + return; } - auto list = cJSON_GetObjectItem(root, "processNameMap"); + g_maxCallstack = std::max(level, g_maxCallstack); + int size = cJSON_GetArraySize(list); + for (int i = 0; i < size; i++) { + auto item = cJSON_GetArrayItem(list, i); + auto it = cJSON_GetObjectItem(item, "callStack"); + if (cJSON_GetArraySize(it) > 0) { + CheckLevel(it, level + 1); + } + } +} + +bool CheckSymbolMap(cJSON* root) +{ + auto list = cJSON_GetObjectItem(root, "SymbolMap"); auto size = cJSON_GetArraySize(list); - bool find = false; + vector symbols = {"usleep"}; + int symbolCounts = 0; for (int i = 0; i < size; i++) { auto item = cJSON_GetArrayItem(list, i); - if (std::string(item->valuestring).find(SubCommandRecordTest::testProcesses) != std::string::npos) { - find = true; - break; + auto it = cJSON_GetObjectItem(item, "symbol"); + for (auto symbol: symbols) { + if (std::string(it->valuestring).find(SubCommandRecordTest::testProcesses) != std::string::npos) { + symbolCounts++; + } } } - if (!find) { + if (symbolCounts < symbols.size()) { return false; } - list = cJSON_GetObjectItem(root, "symbolsFileList"); - size = cJSON_GetArraySize(list); + return true; +} + +bool CheckSymbolsFileList(cJSON* root, const std::string& symbolsFile) +{ + auto list = cJSON_GetObjectItem(root, "symbolsFileList"); + auto size = cJSON_GetArraySize(list); + bool find = false; if (!symbolsFile.empty()) { find = false; for (int i = 0; i < size; i++) { @@ -246,18 +272,55 @@ bool CheckJsonReport(const std::string& fileName, const std::string& symbolsFile return false; } } + return true; +} + +std::string GetProcessId(cJSON* root) +{ + std::string processId; + auto list = cJSON_GetObjectItem(root, "processNameMap"); + auto size = cJSON_GetArraySize(list); + for (int i = 0; i < size; i++) { + auto item = cJSON_GetArrayItem(list, i); + if (std::string(item->valuestring) == "/data/test/hiperf_test_demo") { + processId = std::string(item->string); + } + } + return processId; +} + +bool CheckJsonReport(const std::string& fileName, const std::string& symbolsFile) +{ + cJSON* root = ParseJson(fileName.c_str()); + if (root == nullptr) { + return false; + } + std::string processId = GetProcessId(root); + if (processId.empty()) { + return false; + } + if (!CheckSymbolMap(root)) { + return false; + } + if (!CheckSymbolsFileList(root, symbolsFile)) { + return false; + } auto listRecord = cJSON_GetObjectItem(root, "recordSampleInfo"); if (cJSON_GetArraySize(listRecord) <= 0) { return false; } auto itemRecord = cJSON_GetArrayItem(listRecord, 0); auto listProcesses = cJSON_GetObjectItem(itemRecord, "processes"); - if (cJSON_GetArraySize(listProcesses) <= 0) { - return false; + cJSON* listThreads = nullptr; + for (int i = 0; i < cJSON_GetArraySize(listProcesses); i++) { + auto item = cJSON_GetArrayItem(listProcesses, i); + auto it = cJSON_GetObjectItem(item, "pid"); + if (std::to_string(it->valueint) == processId) { + listThreads = cJSON_GetObjectItem(item, "threads"); + break; + } } - auto itemProcesses = cJSON_GetArrayItem(listProcesses, index); - auto listThreads = cJSON_GetObjectItem(itemProcesses, "threads"); - if (cJSON_GetArraySize(listThreads) <= 0) { + if (listThreads == nullptr || cJSON_GetArraySize(listThreads) <= 0) { return false; } auto itemThreads = cJSON_GetArrayItem(listThreads, 0); @@ -267,7 +330,8 @@ bool CheckJsonReport(const std::string& fileName, const std::string& symbolsFile } auto itemCallOrder = cJSON_GetObjectItem(itemThreads, "CallOrder"); auto itemCallStack = cJSON_GetObjectItem(itemCallOrder, "callStack"); - if (cJSON_GetArraySize(itemCallStack) <= 0) { + CheckLevel(itemCallStack, 0); + if (g_maxCallstack < 1) { return false; } return true; @@ -2304,8 +2368,9 @@ HWTEST_F(SubCommandRecordTest, CheckProductCfg, TestSize.Level1) HWTEST_F(SubCommandRecordTest, TestOnSubCommand_control01, TestSize.Level1) { ASSERT_TRUE(RunCmd("hiperf record --control stop")); - EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control prepare -a -o /data/local/tmp/perf_control01.data", - {"create control hiperf sampling success"}), + EXPECT_EQ(CheckTraceCommandOutput( + "hiperf record --control prepare -a --exclude-hiperf -o /data/local/tmp/perf_control01.data -s dwarf", + {"create control hiperf sampling success"}), true); EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control start", {"start sampling success"}), true); @@ -2316,7 +2381,7 @@ HWTEST_F(SubCommandRecordTest, TestOnSubCommand_control01, TestSize.Level1) "hiperf report --json -i /data/local/tmp/perf_control01.data -o /data/local/tmp/perf.json", {"report done"}), true); - EXPECT_TRUE(CheckJsonReport("/data/local/tmp/perf.json", "/system/bin/hiperf", 1)); + EXPECT_TRUE(CheckJsonReport("/data/local/tmp/perf.json", "/system/bin/hiperf")); } /** @@ -2329,7 +2394,7 @@ HWTEST_F(SubCommandRecordTest, TestOnSubCommand_control_app, TestSize.Level1) ASSERT_TRUE(RunCmd("hiperf record --control stop")); const std::string cmd = "hiperf record --control prepare --app " + SubCommandRecordTest::testProcesses + - " -o /data/local/tmp/perf_control_app.data"; + " -o /data/local/tmp/perf_control_app.data -s dwarf"; EXPECT_EQ(CheckTraceCommandOutput(cmd, {"create control hiperf sampling success"}), true); EXPECT_EQ(CheckTraceCommandOutput("hiperf record --control start", {"start sampling success"}), diff --git a/test/unittest/common/native/subcommand_stat_test.cpp b/test/unittest/common/native/subcommand_stat_test.cpp index c87c083..d26ad53 100644 --- a/test/unittest/common/native/subcommand_stat_test.cpp +++ b/test/unittest/common/native/subcommand_stat_test.cpp @@ -81,9 +81,16 @@ public: std::mutex SubCommandStatTest::mtx; std::condition_variable SubCommandStatTest::cv; -void SubCommandStatTest::SetUpTestCase() {} +void SubCommandStatTest::SetUpTestCase() +{ + chmod("/data/test/hiperf_test_demo", 0755); // 0755 : -rwxr-xr-x + system("/data/test/hiperf_test_demo &"); +} -void SubCommandStatTest::TearDownTestCase() {} +void SubCommandStatTest::TearDownTestCase() +{ + system("kill -9 `pidof hiperf_test_demo`"); +} void SubCommandStatTest::SetUp() { @@ -2441,11 +2448,7 @@ HWTEST_F(SubCommandStatTest, TestOnSubCommand_control04, TestSize.Level1) HWTEST_F(SubCommandStatTest, TestOnSubCommand_control05, TestSize.Level1) { ASSERT_TRUE(RemoveFile(TEST_FILE)); - std::string testProcesses = "com.ohos.launcher"; - if (!CheckTestApp(testProcesses)) { - testProcesses = "hiview"; - } - std::string testCmd = "hiperf stat --control prepare --app " + testProcesses + " --restart"; + std::string testCmd = "hiperf stat --control prepare --app hiperf_test_demo --restart"; const int waitSeconds = 30; // app restart need 30s const int bufferSeconds = 5; // extra wait 5s const std::string expectedStr = "was not stopped within 30 seconds"; diff --git a/test/unittest/common/native/utilities_test.cpp b/test/unittest/common/native/utilities_test.cpp index cc4f8a9..613e2d1 100644 --- a/test/unittest/common/native/utilities_test.cpp +++ b/test/unittest/common/native/utilities_test.cpp @@ -39,9 +39,16 @@ public: const int sleepTime_ = {500}; }; -void UtilitiesTest::SetUpTestCase() {} +void UtilitiesTest::SetUpTestCase() +{ + chmod("/data/test/hiperf_test_demo", 0755); // 0755 : -rwxr-xr-x + system("/data/test/hiperf_test_demo &"); +} -void UtilitiesTest::TearDownTestCase() {} +void UtilitiesTest::TearDownTestCase() +{ + system("kill -9 `pidof hiperf_test_demo`"); +} void UtilitiesTest::SetUp() {} @@ -1009,11 +1016,7 @@ HWTEST_F(UtilitiesTest, IsNumericInvalidWithAlpha, TestSize.Level1) */ HWTEST_F(UtilitiesTest, IsDebugableApp, TestSize.Level1) { - std::string testProcesses = "com.ohos.launcher"; - if (!CheckTestApp(testProcesses)) { - testProcesses = "hiview"; - } - EXPECT_FALSE(IsDebugableApp(testProcesses)); + EXPECT_FALSE(IsDebugableApp("hiperf_test_demo")); } } // namespace HiPerf } // namespace Developtools diff --git a/test/unittest/resource/ohos_test.xml b/test/unittest/resource/ohos_test.xml index e3354ca..e0cf8d5 100644 --- a/test/unittest/resource/ohos_test.xml +++ b/test/unittest/resource/ohos_test.xml @@ -16,6 +16,7 @@ +