/* * Copyright (c) 2021-2024 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 "faultloggerd_performance_test.h" #include #include #include #include "dfx_define.h" #include "dfx_dump_catcher.h" #include "dfx_test_util.h" using namespace OHOS::HiviewDFX; using namespace testing::ext; using namespace std; namespace { static const int PERFORMANCE_TEST_NUMBER_ONE_HUNDRED = 100; static const double PERFORMANCE_TEST_MAX_UNWIND_TIME_S = 0.03; static const double PERFORMANCE_TEST_MAX_UNWIND_TIME_NEW_S = 0.04; clock_t GetStartTime() { return clock(); } double GetStopTime(clock_t befor) { clock_t startTimer = clock(); return ((startTimer - befor) / double(CLOCKS_PER_SEC)); } } void FaultPerformanceTest::SetUpTestCase(void) { } void FaultPerformanceTest::TearDownTestCase(void) { } void FaultPerformanceTest::SetUp(void) { GTEST_LOG_(INFO) << "SetUp"; FaultPerformanceTest::StartRootCrasherLoop(); } void FaultPerformanceTest::TearDown(void) { GTEST_LOG_(INFO) << "TearDown"; FaultPerformanceTest::KillCrasherLoopForSomeCase(); } int FaultPerformanceTest::looprootPid = 0; std::string FaultPerformanceTest::ForkAndRootCommands(const std::vector& cmds) { int rootuid = 0; setuid(rootuid); system("/data/crasher_c thread-Loop &"); std::string procCMD = "pgrep 'crasher'"; GTEST_LOG_(INFO) << "threadCMD = " << procCMD; FILE *procFileInfo = nullptr; procFileInfo = popen(procCMD.c_str(), "r"); if (procFileInfo == nullptr) { perror("popen execute failed"); exit(1); } std::string pidLog; char result_buf_shell[NAME_BUF_LEN] = { 0, }; if (fgets(result_buf_shell, sizeof(result_buf_shell), procFileInfo) != nullptr) { pidLog = result_buf_shell; looprootPid = atoi(pidLog.c_str()); } pclose(procFileInfo); return std::to_string(looprootPid); } void FaultPerformanceTest::StartRootCrasherLoop() { int rootuid = 0; setuid(rootuid); std::vector cmds { "crasher", "thread-Loop" }; FaultPerformanceTest::ForkAndRootCommands(cmds); if (looprootPid == 0) { exit(0); } } void FaultPerformanceTest::KillCrasherLoopForSomeCase() { int rootuid = 0; setuid(rootuid); system(("kill -9 " + std::to_string(FaultPerformanceTest::looprootPid)).c_str()); } namespace { /** * @tc.name: FaultPerformanceTest001 * @tc.desc: test DumpCatch API: PID(root), TID(root) * @tc.type: PERF */ HWTEST_F (FaultPerformanceTest, FaultPerformanceTest001, TestSize.Level2) { GTEST_LOG_(INFO) << "FaultPerformanceTest001: start."; DfxDumpCatcher dumplog; std::string msg; clock_t befor = GetStartTime(); for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) { dumplog.DumpCatch(FaultPerformanceTest::looprootPid, FaultPerformanceTest::looprootPid, msg); } GTEST_LOG_(INFO) << "DumpCatch API Performance time(PID(root), TID(root)): " << GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED << "s"; double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S; double realTime = GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest001 Failed"; GTEST_LOG_(INFO) << "FaultPerformanceTest001: end."; } /** * @tc.name: FaultPerformanceTest002 * @tc.desc: test DumpCatch API: PID(root), TID(0) * @tc.type: PERF */ HWTEST_F (FaultPerformanceTest, FaultPerformanceTest002, TestSize.Level2) { GTEST_LOG_(INFO) << "FaultPerformanceTest002: start."; DfxDumpCatcher dumplog; std::string msg; clock_t befor = GetStartTime(); for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) { dumplog.DumpCatch(FaultPerformanceTest::looprootPid, 0, msg); usleep(200000); // 200000 : sleep 200ms } GTEST_LOG_(INFO) << "DumpCatch API Performance time(PID(root), TID(0)): " << (GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED) << "s"; double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S; double realTime = (GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED) - 0.2; // 0.2 : 200ms EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest002 Failed"; GTEST_LOG_(INFO) << "FaultPerformanceTest002: end."; } /** * @tc.name: FaultPerformanceTest003 * @tc.desc: test dumpcatcher command: PID(root), TID(root) * @tc.type: PERF */ HWTEST_F (FaultPerformanceTest, FaultPerformanceTest003, TestSize.Level2) { GTEST_LOG_(INFO) << "FaultPerformanceTest003: start."; std::string procCMD = "dumpcatcher -p " + std::to_string(FaultPerformanceTest::looprootPid) + " -t "+ std::to_string(FaultPerformanceTest::looprootPid); clock_t befor = GetStartTime(); for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) { ExecuteCommands(procCMD); } double timeInterval = GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; GTEST_LOG_(INFO) << "dumpcatcher Command Performance time(PID(root), TID(root)): " << timeInterval << "s"; double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S; double realTime = GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest003 Failed"; GTEST_LOG_(INFO) << "FaultPerformanceTest003: end."; } /** * @tc.name: FaultPerformanceTest004 * @tc.desc: test DumpCatch API: PID(root) * @tc.type: PERF */ HWTEST_F (FaultPerformanceTest, FaultPerformanceTest004, TestSize.Level2) { GTEST_LOG_(INFO) << "FaultPerformanceTest004: start."; std::string procCMD = "dumpcatcher -p " + std::to_string(FaultPerformanceTest::looprootPid); clock_t befor = GetStartTime(); for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) { ExecuteCommands(procCMD); } GTEST_LOG_(INFO) << "dumpcatcher Command Performance time(PID(root)): " << (GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED) << "s"; double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S; double realTime = GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest004 Failed"; GTEST_LOG_(INFO) << "FaultPerformanceTest004: end."; } /** * @tc.name: FaultPerformanceTest005 * @tc.desc: test DumpCatchMultiPid API: PID(root), TID(0) * @tc.type: PERF */ HWTEST_F (FaultPerformanceTest, FaultPerformanceTest005, TestSize.Level2) { GTEST_LOG_(INFO) << "FaultPerformanceTest005: start."; DfxDumpCatcher dumplog; std::string msg; std::string name = "foundation"; int pid = GetProcessPid(name); std::vector multiPid {pid, FaultPerformanceTest::looprootPid}; clock_t befor = GetStartTime(); for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) { dumplog.DumpCatchMultiPid(multiPid, msg); } double timeInterval = GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; GTEST_LOG_(INFO) << "DumpCatchMultiPid API time(PID(root), PID(foundation)): " << timeInterval << "s"; double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_NEW_S; double realTime = GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest005 Failed"; GTEST_LOG_(INFO) << "FaultPerformanceTest005: end."; } }