1 /*
2 * Copyright (c) 2025 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 <cstring>
17 #include <gtest/gtest.h>
18 #include <sys/utsname.h>
19 #include <thread>
20 #include <unistd.h>
21 #include "dfx_test_util.h"
22 #include "dfx_dump_catcher.h"
23 #include "file_ex.h"
24 #include "lite_perf.h"
25
26 using namespace testing;
27 using namespace testing::ext;
28
29 namespace OHOS {
30 namespace HiviewDFX {
31
32 class LitePerfTest : public testing::Test {
33 public:
34 static void SetUpTestCase();
35 static void TearDownTestCase();
36 void SetUp();
37 void TearDown();
38 };
39
SetUpTestCase()40 void LitePerfTest::SetUpTestCase()
41 {}
42
TearDownTestCase()43 void LitePerfTest::TearDownTestCase()
44 {}
45
SetUp()46 void LitePerfTest::SetUp()
47 {}
48
TearDown()49 void LitePerfTest::TearDown()
50 {}
51
52 /**
53 * @tc.name: LitePerfTest001
54 * @tc.desc: test LitePerf normal
55 * @tc.type: FUNC
56 */
57 HWTEST_F(LitePerfTest, LitePerfTest001, TestSize.Level2)
58 {
59 GTEST_LOG_(INFO) << "LitePerfTest001: start.";
60 if (IsLinuxKernel()) {
61 return;
62 }
63
64 static bool threadExit = false;
65 const int testTimes = 5000;
__anonf18aa6070102null66 auto testThread = [&testTimes] {
67 std::vector<int> tids;
68 int tid = getpid();
69 tids.emplace_back(tid);
70 tids.emplace_back(gettid());
71 int freq = 100;
72 int durationMs = testTimes;
73 bool parseMiniDebugInfo = false;
74 LitePerf litePerf;
75 int ret = litePerf.StartProcessStackSampling(tids, freq, durationMs, parseMiniDebugInfo);
76 EXPECT_EQ(ret, 0);
77 std::string sampleStack;
78 ret = litePerf.CollectSampleStackByTid(tid, sampleStack);
79 EXPECT_EQ(ret, 0);
80 ASSERT_TRUE(sampleStack.size() != 0);
81 ret = litePerf.FinishProcessStackSampling();
82 EXPECT_EQ(ret, 0);
83 threadExit = true;
84 };
85 std::thread th(testThread);
86
87 int times = 0;
88 int sleepTime = 100;
89 while (!threadExit) {
90 if (times > testTimes || sleepTime <= 0) {
91 break;
92 }
93 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
94 times += sleepTime;
95 sleepTime--;
96 }
97 th.join();
98 GTEST_LOG_(INFO) << "LitePerfTest001: end.";
99 }
100
101 /**
102 * @tc.name: LitePerfTest002
103 * @tc.desc: test LitePerf tids empty
104 * @tc.type: FUNC
105 */
106 HWTEST_F(LitePerfTest, LitePerfTest002, TestSize.Level2)
107 {
108 GTEST_LOG_(INFO) << "LitePerfTest002: start.";
109 if (IsLinuxKernel()) {
110 return;
111 }
112 std::vector<int> tids;
113 int tid = getpid();
114 int freq = 100;
115 int durationMs = 5000;
116 bool parseMiniDebugInfo = false;
117 LitePerf litePerf;
118 int ret = litePerf.StartProcessStackSampling(tids, freq, durationMs, parseMiniDebugInfo);
119 EXPECT_EQ(ret, -1);
120 std::string sampleStack;
121 ret = litePerf.CollectSampleStackByTid(tid, sampleStack);
122 EXPECT_EQ(ret, -1);
123 ASSERT_TRUE(sampleStack.size() == 0);
124 ret = litePerf.FinishProcessStackSampling();
125 EXPECT_EQ(ret, 0);
126 GTEST_LOG_(INFO) << "LitePerfTest002: end.";
127 }
128
129 /**
130 * @tc.name: LitePerfTest003
131 * @tc.desc: test LitePerf invalid freq
132 * @tc.type: FUNC
133 */
134 HWTEST_F(LitePerfTest, LitePerfTest003, TestSize.Level2)
135 {
136 GTEST_LOG_(INFO) << "LitePerfTest003: start.";
137 if (IsLinuxKernel()) {
138 return;
139 }
140 std::vector<int> tids;
141 int tid = getpid();
142 tids.emplace_back(tid);
143 int freq = 2000;
144 int durationMs = 5000;
145 bool parseMiniDebugInfo = false;
146 LitePerf litePerf;
147 int ret = litePerf.StartProcessStackSampling(tids, freq, durationMs, parseMiniDebugInfo);
148 EXPECT_EQ(ret, -1);
149 std::string sampleStack;
150 ret = litePerf.CollectSampleStackByTid(tid, sampleStack);
151 EXPECT_EQ(ret, -1);
152 ASSERT_TRUE(sampleStack.size() == 0);
153 ret = litePerf.FinishProcessStackSampling();
154 EXPECT_EQ(ret, 0);
155 GTEST_LOG_(INFO) << "LitePerfTest003: end.";
156 }
157
158 /**
159 * @tc.name: LitePerfTest004
160 * @tc.desc: test LitePerf invalid freq -1
161 * @tc.type: FUNC
162 */
163 HWTEST_F(LitePerfTest, LitePerfTest004, TestSize.Level2)
164 {
165 GTEST_LOG_(INFO) << "LitePerfTest004: start.";
166 if (IsLinuxKernel()) {
167 return;
168 }
169 std::vector<int> tids;
170 int tid = getpid();
171 tids.emplace_back(tid);
172 int freq = -1;
173 int durationMs = 5000;
174 bool parseMiniDebugInfo = false;
175 LitePerf litePerf;
176 int ret = litePerf.StartProcessStackSampling(tids, freq, durationMs, parseMiniDebugInfo);
177 EXPECT_EQ(ret, -1);
178 std::string sampleStack;
179 ret = litePerf.CollectSampleStackByTid(tid, sampleStack);
180 EXPECT_EQ(ret, -1);
181 ASSERT_TRUE(sampleStack.size() == 0);
182 ret = litePerf.FinishProcessStackSampling();
183 EXPECT_EQ(ret, 0);
184 GTEST_LOG_(INFO) << "LitePerfTest004: end.";
185 }
186
187 /**
188 * @tc.name: LitePerfTest005
189 * @tc.desc: test LitePerf invalid time
190 * @tc.type: FUNC
191 */
192 HWTEST_F(LitePerfTest, LitePerfTest005, TestSize.Level2)
193 {
194 GTEST_LOG_(INFO) << "LitePerfTest005: start.";
195 if (IsLinuxKernel()) {
196 return;
197 }
198 std::vector<int> tids;
199 int tid = getpid();
200 tids.emplace_back(tid);
201 int freq = 100;
202 int durationMs = 20000;
203 bool parseMiniDebugInfo = false;
204 LitePerf litePerf;
205 int ret = litePerf.StartProcessStackSampling(tids, freq, durationMs, parseMiniDebugInfo);
206 EXPECT_EQ(ret, -1);
207 std::string sampleStack;
208 ret = litePerf.CollectSampleStackByTid(tid, sampleStack);
209 EXPECT_EQ(ret, -1);
210 ASSERT_TRUE(sampleStack.size() == 0);
211 ret = litePerf.FinishProcessStackSampling();
212 EXPECT_EQ(ret, 0);
213 GTEST_LOG_(INFO) << "LitePerfTest005: end.";
214 }
215
216 /**
217 * @tc.name: LitePerfTest006
218 * @tc.desc: test LitePerf invalid time -1
219 * @tc.type: FUNC
220 */
221 HWTEST_F(LitePerfTest, LitePerfTest006, TestSize.Level2)
222 {
223 GTEST_LOG_(INFO) << "LitePerfTest006: start.";
224 if (IsLinuxKernel()) {
225 return;
226 }
227 std::vector<int> tids;
228 int tid = getpid();
229 tids.emplace_back(tid);
230 int freq = 100;
231 int durationMs = -1;
232 bool parseMiniDebugInfo = false;
233 LitePerf litePerf;
234 int ret = litePerf.StartProcessStackSampling(tids, freq, durationMs, parseMiniDebugInfo);
235 EXPECT_EQ(ret, -1);
236 std::string sampleStack;
237 ret = litePerf.CollectSampleStackByTid(tid, sampleStack);
238 EXPECT_EQ(ret, -1);
239 ASSERT_TRUE(sampleStack.size() == 0);
240 ret = litePerf.FinishProcessStackSampling();
241 EXPECT_EQ(ret, 0);
242 GTEST_LOG_(INFO) << "LitePerfTest006: end.";
243 }
244
245 /**
246 * @tc.name: LitePerfTest007
247 * @tc.desc: test LitePerf invalid tids
248 * @tc.type: FUNC
249 */
250 HWTEST_F(LitePerfTest, LitePerfTest007, TestSize.Level2)
251 {
252 GTEST_LOG_(INFO) << "LitePerfTest007: start.";
253 if (IsLinuxKernel()) {
254 return;
255 }
256 std::vector<int> tids {1, 2, 3, 4, 5};
257 int freq = 100;
258 int durationMs = 5000;
259 bool parseMiniDebugInfo = false;
260 LitePerf litePerf;
261 int ret = litePerf.StartProcessStackSampling(tids, freq, durationMs, parseMiniDebugInfo);
262 EXPECT_EQ(ret, -1);
263 for (auto tid : tids) {
264 std::string sampleStack;
265 sampleStack.clear();
266 ret = litePerf.CollectSampleStackByTid(tid, sampleStack);
267 EXPECT_EQ(ret, -1);
268 }
269 ret = litePerf.FinishProcessStackSampling();
270 EXPECT_EQ(ret, 0);
271 GTEST_LOG_(INFO) << "LitePerfTest007: end.";
272 }
273
274 /**
275 * @tc.name: LitePerfTest008
276 * @tc.desc: test LitePerf and DumpCatcher as the same time
277 * @tc.type: FUNC
278 */
279 HWTEST_F(LitePerfTest, LitePerfTest008, TestSize.Level2)
280 {
281 GTEST_LOG_(INFO) << "LitePerfTest008: start.";
282 if (IsLinuxKernel()) {
283 return;
284 }
285
286 int fd[2];
287 EXPECT_TRUE(CreatePipeFd(fd));
288
289 pid_t pid = 0;
290 pid = fork();
291 if (pid < 0) {
292 GTEST_LOG_(INFO) << "LitePerfTest008: Failed to vfork.";
293 } else if (pid == 0) {
294 NotifyProcStart(fd);
295 std::this_thread::sleep_for(std::chrono::seconds(1));
296 pid_t parentPid = getppid();
297 GTEST_LOG_(INFO) << "LitePerfTest008: parentPid: " << parentPid;
298 DfxDumpCatcher dumplog;
299 string msg = "";
300 bool ret = dumplog.DumpCatch(parentPid, 0, msg);
301 EXPECT_TRUE(ret) << "LitePerfTest008: DumpCatch0 msg Failed.";
302 } else {
303 WaitProcStart(fd);
304 std::vector<int> tids;
305 int tid = getpid();
306 GTEST_LOG_(INFO) << "pid: " << tid;
307 tids.emplace_back(tid);
308 int freq = 100;
309 int durationMs = 5000;
310 bool parseMiniDebugInfo = false;
311 LitePerf litePerf;
312 int ret = litePerf.StartProcessStackSampling(tids, freq, durationMs, parseMiniDebugInfo);
313 EXPECT_EQ(ret, 0) << "LitePerfTest008: StartProcessStackSampling Failed.";
314 std::string sampleStack;
315 litePerf.CollectSampleStackByTid(tid, sampleStack);
316 ret = litePerf.FinishProcessStackSampling();
317 EXPECT_EQ(ret, 0);
318 }
319 GTEST_LOG_(INFO) << "LitePerfTest008: end.";
320 }
321 } // namespace HiviewDFX
322 } // namespace OHOS
323