diff --git a/demo/cpp/hiperf_demo.cpp b/demo/cpp/hiperf_demo.cpp index eed836ffd7c0283b7688fc0e2f9250af3715055e..f7aa6422ec07743b97fa8b2088267b30383705f2 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 aabe9d065cf4bff5c576209eca73f44f7eaa59fc..e42c72bbe79fd18622b85a49b607ecdd6545b502 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 74717e1d5d41f9bac451ffd522c91fcdd5d808e8..ef7fd6bcd45fe9fcc9462f870e516baad1a7a4df 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 09588666598f2676ec5ac22b13ff84e520446361..b89cfe8eda823f0f3716d242bde46b93c0c07fac 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 0000000000000000000000000000000000000000..cf5551b34ac7da8705c5d485919e8871ec579c3f --- /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 4cdf976db7333b2ddb5e05f662824f2596980c2c..001f4f2fd08efaa30753e0b5ebbb7ab056d042a0 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 32f6c87ee62b7274a44c6c1b0d410c82c0cb47fd..2dbed387cbd3469342851bd8552878a7aea80b99 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 c87c083ab98f0b26051dd81f8df350786fd24069..d26ad5302926d0dffcd9ddd666bbf9f0bb053974 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 cc4f8a940fc2d0ef4eb77a8f42372e81cb002de3..613e2d11f3ee6d3cdf48c1966f09e562d28ae4a7 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 e3354ca35c3f24cecae987ec42b78200597ef92f..e0cf8d5143c2c38f9178a9bbd1097e6ba7e7e1a9 100644 --- a/test/unittest/resource/ohos_test.xml +++ b/test/unittest/resource/ohos_test.xml @@ -16,6 +16,7 @@ +