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