1 /*
2  * Copyright (c) 2021-2024 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 "faultloggerd_performance_test.h"
17 
18 #include <string>
19 #include <unistd.h>
20 #include <vector>
21 
22 #include "dfx_define.h"
23 #include "dfx_dump_catcher.h"
24 #include "dfx_test_util.h"
25 
26 using namespace OHOS::HiviewDFX;
27 using namespace testing::ext;
28 using namespace std;
29 
30 namespace {
31 static const int PERFORMANCE_TEST_NUMBER_ONE_HUNDRED = 100;
32 static const double PERFORMANCE_TEST_MAX_UNWIND_TIME_S = 0.03;
33 static const double PERFORMANCE_TEST_MAX_UNWIND_TIME_NEW_S = 0.04;
34 
GetStartTime()35 clock_t GetStartTime()
36 {
37     return clock();
38 }
39 
GetStopTime(clock_t befor)40 double GetStopTime(clock_t befor)
41 {
42     clock_t startTimer = clock();
43     return  ((startTimer - befor) / double(CLOCKS_PER_SEC));
44 }
45 }
46 
SetUpTestCase(void)47 void FaultPerformanceTest::SetUpTestCase(void)
48 {
49 }
50 
TearDownTestCase(void)51 void FaultPerformanceTest::TearDownTestCase(void)
52 {
53 }
54 
SetUp(void)55 void FaultPerformanceTest::SetUp(void)
56 {
57     GTEST_LOG_(INFO) << "SetUp";
58     FaultPerformanceTest::StartRootCrasherLoop();
59 }
60 
TearDown(void)61 void FaultPerformanceTest::TearDown(void)
62 {
63     GTEST_LOG_(INFO) << "TearDown";
64     FaultPerformanceTest::KillCrasherLoopForSomeCase();
65 }
66 
67 int FaultPerformanceTest::looprootPid = 0;
68 
ForkAndRootCommands(const std::vector<std::string> & cmds)69 std::string FaultPerformanceTest::ForkAndRootCommands(const std::vector<std::string>& cmds)
70 {
71     int rootuid = 0;
72     setuid(rootuid);
73     system("/data/crasher_c thread-Loop &");
74     std::string procCMD = "pgrep 'crasher'";
75     GTEST_LOG_(INFO) << "threadCMD = " << procCMD;
76     FILE *procFileInfo = nullptr;
77     procFileInfo = popen(procCMD.c_str(), "r");
78     if (procFileInfo == nullptr) {
79         perror("popen execute failed");
80         exit(1);
81     }
82     std::string pidLog;
83     char result_buf_shell[NAME_BUF_LEN] = { 0, };
84     if (fgets(result_buf_shell, sizeof(result_buf_shell), procFileInfo) != nullptr) {
85         pidLog = result_buf_shell;
86         looprootPid = atoi(pidLog.c_str());
87     }
88     pclose(procFileInfo);
89     return std::to_string(looprootPid);
90 }
91 
StartRootCrasherLoop()92 void FaultPerformanceTest::StartRootCrasherLoop()
93 {
94     int rootuid = 0;
95     setuid(rootuid);
96     std::vector<std::string> cmds { "crasher", "thread-Loop" };
97     FaultPerformanceTest::ForkAndRootCommands(cmds);
98     if (looprootPid == 0) {
99         exit(0);
100     }
101 }
102 
KillCrasherLoopForSomeCase()103 void FaultPerformanceTest::KillCrasherLoopForSomeCase()
104 {
105     int rootuid = 0;
106     setuid(rootuid);
107     system(("kill -9 " + std::to_string(FaultPerformanceTest::looprootPid)).c_str());
108 }
109 
110 namespace {
111 /**
112  * @tc.name: FaultPerformanceTest001
113  * @tc.desc: test DumpCatch API: PID(root), TID(root)
114  * @tc.type: PERF
115  */
116 HWTEST_F (FaultPerformanceTest, FaultPerformanceTest001, TestSize.Level2)
117 {
118     GTEST_LOG_(INFO) << "FaultPerformanceTest001: start.";
119     DfxDumpCatcher dumplog;
120     std::string msg;
121     clock_t befor = GetStartTime();
122     for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) {
123         dumplog.DumpCatch(FaultPerformanceTest::looprootPid, FaultPerformanceTest::looprootPid, msg);
124     }
125     GTEST_LOG_(INFO) << "DumpCatch API Performance time(PID(root), TID(root)): " <<
126         GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED << "s";
127     double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S;
128     double realTime = GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
129     EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest001 Failed";
130     GTEST_LOG_(INFO) << "FaultPerformanceTest001: end.";
131 }
132 
133 /**
134  * @tc.name: FaultPerformanceTest002
135  * @tc.desc: test DumpCatch API: PID(root), TID(0)
136  * @tc.type: PERF
137  */
138 HWTEST_F (FaultPerformanceTest, FaultPerformanceTest002, TestSize.Level2)
139 {
140     GTEST_LOG_(INFO) << "FaultPerformanceTest002: start.";
141     DfxDumpCatcher dumplog;
142     std::string msg;
143     clock_t befor = GetStartTime();
144     for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) {
145         dumplog.DumpCatch(FaultPerformanceTest::looprootPid, 0, msg);
146         usleep(200000); // 200000 : sleep 200ms
147     }
148     GTEST_LOG_(INFO) << "DumpCatch API Performance time(PID(root), TID(0)): " <<
149         (GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED) << "s";
150     double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S;
151     double realTime = (GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED) - 0.2; // 0.2 : 200ms
152     EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest002 Failed";
153     GTEST_LOG_(INFO) << "FaultPerformanceTest002: end.";
154 }
155 
156 /**
157  * @tc.name: FaultPerformanceTest003
158  * @tc.desc: test dumpcatcher command: PID(root), TID(root)
159  * @tc.type: PERF
160  */
161 HWTEST_F (FaultPerformanceTest, FaultPerformanceTest003, TestSize.Level2)
162 {
163     GTEST_LOG_(INFO) << "FaultPerformanceTest003: start.";
164     std::string procCMD = "dumpcatcher -p " + std::to_string(FaultPerformanceTest::looprootPid) + " -t "+
165         std::to_string(FaultPerformanceTest::looprootPid);
166     clock_t befor = GetStartTime();
167     for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) {
168         ExecuteCommands(procCMD);
169     }
170     double timeInterval = GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
171     GTEST_LOG_(INFO) << "dumpcatcher Command Performance time(PID(root), TID(root)): " << timeInterval << "s";
172     double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S;
173     double realTime = GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
174     EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest003 Failed";
175     GTEST_LOG_(INFO) << "FaultPerformanceTest003: end.";
176 }
177 
178 /**
179  * @tc.name: FaultPerformanceTest004
180  * @tc.desc: test DumpCatch API: PID(root)
181  * @tc.type: PERF
182  */
183 HWTEST_F (FaultPerformanceTest, FaultPerformanceTest004, TestSize.Level2)
184 {
185     GTEST_LOG_(INFO) << "FaultPerformanceTest004: start.";
186     std::string procCMD = "dumpcatcher -p " + std::to_string(FaultPerformanceTest::looprootPid);
187     clock_t befor = GetStartTime();
188     for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) {
189         ExecuteCommands(procCMD);
190     }
191     GTEST_LOG_(INFO) << "dumpcatcher Command Performance time(PID(root)): " <<
192         (GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED) << "s";
193 
194     double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S;
195     double realTime = GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
196     EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest004 Failed";
197     GTEST_LOG_(INFO) << "FaultPerformanceTest004: end.";
198 }
199 
200 /**
201  * @tc.name: FaultPerformanceTest005
202  * @tc.desc: test DumpCatchMultiPid API: PID(root), TID(0)
203  * @tc.type: PERF
204  */
205 HWTEST_F (FaultPerformanceTest, FaultPerformanceTest005, TestSize.Level2)
206 {
207     GTEST_LOG_(INFO) << "FaultPerformanceTest005: start.";
208     DfxDumpCatcher dumplog;
209     std::string msg;
210     std::string name = "foundation";
211     int pid = GetProcessPid(name);
212     std::vector<int> multiPid {pid, FaultPerformanceTest::looprootPid};
213     clock_t befor = GetStartTime();
214     for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) {
215         dumplog.DumpCatchMultiPid(multiPid, msg);
216     }
217     double timeInterval = GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
218     GTEST_LOG_(INFO) << "DumpCatchMultiPid API time(PID(root), PID(foundation)): " << timeInterval << "s";
219     double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_NEW_S;
220     double realTime = GetStopTime(befor) / PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
221     EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest005 Failed";
222     GTEST_LOG_(INFO) << "FaultPerformanceTest005: end.";
223 }
224 }
225