• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 /* This files contains faultlog performance st test case. */
17 
18 #include "faultloggerd_performance_test.h"
19 
20 #include <cerrno>
21 #include <cstdio>
22 #include <cstring>
23 #include <ctime>
24 #include <dirent.h>
25 #include <fcntl.h>
26 #include <fstream>
27 #include <iostream>
28 #include <memory>
29 #include <pthread.h>
30 #include <securec.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <string>
34 #include <sys/stat.h>
35 #include <sys/time.h>
36 #include <sys/types.h>
37 #include <sys/wait.h>
38 #include <time.h>
39 #include <unistd.h>
40 #include <vector>
41 #include "dfx_define.h"
42 #include "dfx_dump_catcher.h"
43 #include "directory_ex.h"
44 #include "file_ex.h"
45 #include "syscall.h"
46 
47 
48 using namespace OHOS::HiviewDFX;
49 using namespace testing::ext;
50 using namespace std;
51 
52 namespace {
53 static const int PERFORMANCE_TEST_NUMBER_ONE_HUNDRED = 100;
54 static const double PERFORMANCE_TEST_MAX_UNWIND_TIME_S = 0.03;
55 static const double PERFORMANCE_TEST_MAX_UNWIND_TIME_NEW_S = 0.04;
56 
GetStartTime()57 clock_t GetStartTime ()
58 {
59     return clock();
60 }
61 
GetStopTime(clock_t befor)62 double GetStopTime(clock_t befor)
63 {
64     clock_t StartTimer = clock();
65     return  ((StartTimer - befor) / double(CLOCKS_PER_SEC));
66 }
67 }
68 
SetUpTestCase(void)69 void FaultPerformanceTest::SetUpTestCase(void)
70 {
71 }
72 
TearDownTestCase(void)73 void FaultPerformanceTest::TearDownTestCase(void)
74 {
75 }
76 
SetUp(void)77 void FaultPerformanceTest::SetUp(void)
78 {
79     GTEST_LOG_(INFO) << "SetUp";
80     FaultPerformanceTest::StartRootCrasherLoop();
81 }
82 
TearDown(void)83 void FaultPerformanceTest::TearDown(void)
84 {
85     GTEST_LOG_(INFO) << "TearDown";
86     FaultPerformanceTest::KillCrasherLoopForSomeCase();
87 }
88 
89 int FaultPerformanceTest::looprootPid = 0;
ProcessDumpCommands(const std::string cmds)90 std::string FaultPerformanceTest::ProcessDumpCommands(const std::string cmds)
91 {
92     GTEST_LOG_(INFO) << "threadCMD = " << cmds;
93     FILE *procFileInfo = nullptr;
94     std::string cmdLog;
95     procFileInfo = popen(cmds.c_str(), "r");
96     if (procFileInfo == nullptr) {
97         perror("popen execute failed");
98         exit(1);
99     }
100     char result_buf_shell[NAME_LEN] = {'\0'};
101     while (fgets(result_buf_shell, sizeof(result_buf_shell), procFileInfo) != nullptr) {
102         cmdLog = cmdLog + result_buf_shell;
103     }
104     pclose(procFileInfo);
105     return cmdLog;
106 }
107 
ForkAndRootCommands(const std::vector<std::string> & cmds)108 std::string FaultPerformanceTest::ForkAndRootCommands(const std::vector<std::string>& cmds)
109 {
110     int rootuid = 0;
111     setuid(rootuid);
112     system("/data/crasher_c thread-Loop &");
113     std::string procCMD = "pgrep 'crasher'";
114     GTEST_LOG_(INFO) << "threadCMD = " << procCMD;
115     FILE *procFileInfo = nullptr;
116     procFileInfo = popen(procCMD.c_str(), "r");
117     if (procFileInfo == nullptr) {
118         perror("popen execute failed");
119         exit(1);
120     }
121     std::string pidLog;
122     char result_buf_shell[NAME_LEN] = { 0, };
123     if (fgets(result_buf_shell, sizeof(result_buf_shell), procFileInfo) != nullptr) {
124         pidLog = result_buf_shell;
125         looprootPid = atoi(pidLog.c_str());
126     }
127     pclose(procFileInfo);
128     return std::to_string(looprootPid);
129 }
130 
StartRootCrasherLoop()131 void FaultPerformanceTest::StartRootCrasherLoop()
132 {
133     int rootuid = 0;
134     setuid(rootuid);
135     std::vector<std::string> cmds { "crasher", "thread-Loop" };
136     FaultPerformanceTest::ForkAndRootCommands(cmds);
137     if (looprootPid == 0) {
138         exit(0);
139     }
140 }
141 
KillCrasherLoopForSomeCase()142 void FaultPerformanceTest::KillCrasherLoopForSomeCase()
143 {
144     int rootuid = 0;
145     setuid(rootuid);
146     system(("kill -9 " + std::to_string(FaultPerformanceTest::looprootPid)).c_str());
147 }
148 
getApplyPid(std::string applyName)149 int FaultPerformanceTest::getApplyPid(std::string applyName)
150 {
151     std::string procCMD = "pgrep '" + applyName + "'";
152     GTEST_LOG_(INFO) << "threadCMD = " << procCMD;
153     FILE *procFileInfo = nullptr;
154     procFileInfo = popen(procCMD.c_str(), "r");
155     if (procFileInfo == nullptr) {
156         perror("popen execute failed");
157         exit(1);
158     }
159     std::string applyPid;
160     char result_buf_shell[100] = { 0, };
161     while (fgets(result_buf_shell, sizeof(result_buf_shell), procFileInfo) != nullptr) {
162         applyPid = result_buf_shell;
163         GTEST_LOG_(INFO) << "applyPid: " << applyPid;
164     }
165     pclose(procFileInfo);
166     GTEST_LOG_(INFO) << applyPid;
167     int intApplyPid = std::atoi(applyPid.c_str());
168     return intApplyPid;
169 }
170 
171 namespace {
172 /**
173  * @tc.name: FaultPerformanceTest001
174  * @tc.desc: test DumpCatch API: PID(root), TID(root)
175  * @tc.type: FUNC
176  */
177 HWTEST_F (FaultPerformanceTest, FaultPerformanceTest001, TestSize.Level2)
178 {
179     GTEST_LOG_(INFO) << "FaultPerformanceTest001: start.";
180     DfxDumpCatcher dumplog;
181     std::string msg;
182     clock_t befor = GetStartTime();
183     for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) {
184         dumplog.DumpCatch(FaultPerformanceTest::looprootPid, FaultPerformanceTest::looprootPid, msg);
185     }
186     GTEST_LOG_(INFO) << "DumpCatch API Performance time(PID(root), TID(root)): " << \
187         GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED << "s";
188     double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S;
189     double realTime = GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
190     EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest001 Failed";
191     GTEST_LOG_(INFO) << "FaultPerformanceTest001: end.";
192 }
193 
194 /**
195  * @tc.name: FaultPerformanceTest002
196  * @tc.desc: test DumpCatch API: PID(root), TID(0)
197  * @tc.type: FUNC
198  */
199 HWTEST_F (FaultPerformanceTest, FaultPerformanceTest002, TestSize.Level2)
200 {
201     GTEST_LOG_(INFO) << "FaultPerformanceTest002: start.";
202     DfxDumpCatcher dumplog;
203     std::string msg;
204     clock_t befor = GetStartTime();
205     for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) {
206         dumplog.DumpCatch(FaultPerformanceTest::looprootPid, 0, msg);
207         usleep(200000);
208     }
209     GTEST_LOG_(INFO) << "DumpCatch API Performance time(PID(root), TID(0)): " << \
210         GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED << "s";
211     double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S;
212     double realTime = GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED - 0.2;
213     EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest002 Failed";
214     GTEST_LOG_(INFO) << "FaultPerformanceTest002: end.";
215 }
216 
217 /**
218  * @tc.name: FaultPerformanceTest003
219  * @tc.desc: test dumpcatcher command: PID(root), TID(root)
220  * @tc.type: FUNC
221  */
222 HWTEST_F (FaultPerformanceTest, FaultPerformanceTest003, TestSize.Level2)
223 {
224     GTEST_LOG_(INFO) << "FaultPerformanceTest003: start.";
225     std::string procCMD = "dumpcatcher -p " + std::to_string(FaultPerformanceTest::looprootPid) + " -t "+
226         std::to_string(FaultPerformanceTest::looprootPid);
227     clock_t befor = GetStartTime();
228     for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) {
229         FaultPerformanceTest::ProcessDumpCommands(procCMD);
230     }
231     double timeInterval = GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
232     GTEST_LOG_(INFO) << "dumpcatcher Command Performance time(PID(root), TID(root)): " << timeInterval << "s";
233     double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S;
234     double realTime = GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
235     EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest003 Failed";
236     GTEST_LOG_(INFO) << "FaultPerformanceTest003: end.";
237 }
238 
239 /**
240  * @tc.name: FaultPerformanceTest004
241  * @tc.desc: test DumpCatch API: PID(root)
242  * @tc.type: FUNC
243  */
244 HWTEST_F (FaultPerformanceTest, FaultPerformanceTest004, TestSize.Level2)
245 {
246     GTEST_LOG_(INFO) << "FaultPerformanceTest004: start.";
247     std::string procCMD = "dumpcatcher -p " + std::to_string(FaultPerformanceTest::looprootPid);
248     clock_t befor = GetStartTime();
249     for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) {
250         FaultPerformanceTest::ProcessDumpCommands(procCMD);
251     }
252     GTEST_LOG_(INFO) << "dumpcatcher Command Performance time(PID(root)): " << \
253         GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED << "s";
254 
255     double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S;
256     double realTime = GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
257     EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest004 Failed";
258     GTEST_LOG_(INFO) << "FaultPerformanceTest004: end.";
259 }
260 
261 /**
262  * @tc.name: FaultPerformanceTest005
263  * @tc.desc: test DumpCatchMultiPid API: PID(root), TID(0)
264  * @tc.type: FUNC
265  */
266 HWTEST_F (FaultPerformanceTest, FaultPerformanceTest005, TestSize.Level2)
267 {
268     GTEST_LOG_(INFO) << "FaultPerformanceTest005: start.";
269     DfxDumpCatcher dumplog;
270     std::string msg;
271     std::string apply = "foundation";
272     int applyPid = FaultPerformanceTest::getApplyPid(apply);
273     std::vector<int> multiPid {applyPid, FaultPerformanceTest::looprootPid};
274     clock_t befor = GetStartTime();
275     for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) {
276         dumplog.DumpCatchMultiPid(multiPid, msg);
277     }
278     double timeInterval = GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
279     GTEST_LOG_(INFO) << "DumpCatchMultiPid API time(PID(root), PID(foundation)): " << timeInterval << "s";
280     double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_NEW_S;
281     double realTime = GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
282     EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest005 Failed";
283     GTEST_LOG_(INFO) << "FaultPerformanceTest005: end.";
284 }
285 
286 /**
287  * @tc.name: FaultPerformanceTest006
288  * @tc.desc: test DumpCatchFrame API: app PID(app), TID(0)
289  * @tc.type: FUNC
290  */
291 HWTEST_F (FaultPerformanceTest, FaultPerformanceTest006, TestSize.Level2)
292 {
293     GTEST_LOG_(INFO) << "FaultPerformanceTest006: start.";
294     std::string apply = "test_perfor";
295     int testPid = FaultPerformanceTest::getApplyPid(apply);
296     GTEST_LOG_(INFO) << testPid;
297     DfxDumpCatcher dumplog(testPid);
298     if (!dumplog.InitFrameCatcher()) {
299         GTEST_LOG_(ERROR) << "Failed to suspend thread(" << testPid << ").";
300     }
301     std::vector<std::shared_ptr<DfxFrame>> frameV;
302     clock_t befor = GetStartTime();
303     for (int i = 0; i < PERFORMANCE_TEST_NUMBER_ONE_HUNDRED; i++) {
304         bool ret = dumplog.CatchFrame(testPid, frameV);
305         GTEST_LOG_(INFO) << ret;
306     }
307     double timeInterval = GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
308     GTEST_LOG_(INFO) << "DumpCatchFrame API time(PID(test_per), PID(test_per)):" << timeInterval << "s";
309     double expectTime = PERFORMANCE_TEST_MAX_UNWIND_TIME_S;
310     double realTime = GetStopTime(befor)/PERFORMANCE_TEST_NUMBER_ONE_HUNDRED;
311     EXPECT_EQ(true, realTime < expectTime) << "FaultPerformanceTest006 Failed";
312     GTEST_LOG_(INFO) << "FaultPerformanceTest006: end.";
313 }
314 }
315