1 /*
2 * Copyright (c) 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
17 #include <fcntl.h>
18 #include <filesystem>
19 #include <gtest/gtest.h>
20
21 #if defined(HAS_LIB_SELINUX)
22 #include <selinux/selinux.h>
23 #endif
24
25 #include <sys/socket.h>
26 #include <sys/un.h>
27 #include <thread>
28 #include <unistd.h>
29 #include "dfx_test_util.h"
30 #include "dfx_util.h"
31 #include "faultloggerd_client.h"
32 #include "fault_common_util.h"
33 #include "fault_coredump_service.h"
34 #include "faultloggerd_test.h"
35 #include "fault_logger_daemon.h"
36 #include "smart_fd.h"
37
38 using namespace testing;
39 using namespace testing::ext;
40
41 namespace OHOS {
42 namespace HiviewDFX {
43 class FaultloggerdClientTest : public testing::Test {
44 public:
45 static void SetUpTestCase();
46 static void TearDownTestCase();
47 };
48
TearDownTestCase()49 void FaultloggerdClientTest::TearDownTestCase()
50 {
51 ClearTempFiles();
52 }
53
SetUpTestCase()54 void FaultloggerdClientTest::SetUpTestCase()
55 {
56 FaultLoggerdTestServer::GetInstance();
57 constexpr int waitTime = 1500; // 1.5s;
58 std::this_thread::sleep_for(std::chrono::milliseconds(waitTime));
59 }
60
61 /**
62 * @tc.name: SendSignalToHapWatchdogThreadTest
63 * @tc.desc: Test send signal to watchdog thread
64 * @tc.type: FUNC
65 */
66 HWTEST_F(FaultloggerdClientTest, SendSignalToHapWatchdogThreadTest, TestSize.Level2)
67 {
68 GTEST_LOG_(INFO) << "SendSignalToHapWatchdogThreadTest: start.";
69 pid_t pid = -1;
70 siginfo_t si = {};
71 ASSERT_EQ(FaultCommonUtil::SendSignalToHapWatchdogThread(pid, si), ResponseCode::DEFAULT_ERROR_CODE);
72 GTEST_LOG_(INFO) << "SendSignalToHapWatchdogThreadTest: end.";
73 }
74
75 /**
76 * @tc.name: SendSignalToProcessTest
77 * @tc.desc: SendSignalToProcess
78 * @tc.type: FUNC
79 */
80 HWTEST_F(FaultloggerdClientTest, SendSignalToProcessTest, TestSize.Level2)
81 {
82 GTEST_LOG_(INFO) << "SendSignalToProcessTest: start.";
83 pid_t pid = -1;
84 siginfo_t si = {};
85 ASSERT_EQ(FaultCommonUtil::SendSignalToProcess(pid, si), ResponseCode::REQUEST_SUCCESS);
86 GTEST_LOG_(INFO) << "SendSignalToProcessTest: end.";
87 }
88
89 /**
90 * @tc.name: GetUcredByPeerCredTest
91 * @tc.desc: GetUcredByPeerCred
92 * @tc.type: FUNC
93 */
94 HWTEST_F(FaultloggerdClientTest, GetUcredByPeerCredTest, TestSize.Level2)
95 {
96 GTEST_LOG_(INFO) << "GetUcredByPeerCredTest: start.";
97 int32_t connectionFd = 0;
98 struct ucred rcred;
99 bool result = FaultCommonUtil::GetUcredByPeerCred(rcred, connectionFd);
100 EXPECT_FALSE(result);
101 GTEST_LOG_(INFO) << "GetUcredByPeerCredTest: end.";
102 }
103
104 /**
105 * @tc.name: HandleProcessDumpPidTest001
106 * @tc.desc: HandleProcessDumpPid
107 * @tc.type: FUNC
108 */
109 HWTEST_F(FaultloggerdClientTest, HandleProcessDumpPidTest001, TestSize.Level2)
110 {
111 GTEST_LOG_(INFO) << "HandleProcessDumpPidTest001: start.";
112 int32_t targetPid = 123;
113 int32_t processDumpPid = -1;
114 CoredumpStatusService coredumpStatusService;
115 EXPECT_FALSE(coredumpStatusService.HandleProcessDumpPid(targetPid, processDumpPid));
116
117 GTEST_LOG_(INFO) << "HandleProcessDumpPidTest001: end.";
118 }
119
120 /**
121 * @tc.name: HandleProcessDumpPidTest002
122 * @tc.desc: HandleProcessDumpPid
123 * @tc.type: FUNC
124 */
125 HWTEST_F(FaultloggerdClientTest, HandleProcessDumpPidTest002, TestSize.Level2)
126 {
127 GTEST_LOG_(INFO) << "HandleProcessDumpPidTest002: start.";
128 int32_t targetPid = 123;
129 int32_t processDumpPid = 456;
130 CoredumpStatusService coredumpStatusService;
131 EXPECT_FALSE(coredumpStatusService.HandleProcessDumpPid(targetPid, processDumpPid));
132 GTEST_LOG_(INFO) << "HandleProcessDumpPidTest002: end.";
133 }
134
135 /**
136 * @tc.name: DoCoredumpRequestTest
137 * @tc.desc: DoCoredumpRequest
138 * @tc.type: FUNC
139 */
140 HWTEST_F(FaultloggerdClientTest, DoCoredumpRequestTest, TestSize.Level2)
141 {
142 GTEST_LOG_(INFO) << "DoCoredumpRequestTest: start.";
143 std::string socketName = "test_socket";
144 int32_t connectionFd = 1;
145 CoreDumpRequestData requestData = {};
146 CoredumpService coredumpService;
147 ASSERT_EQ(coredumpService.DoCoredumpRequest(socketName, connectionFd, requestData), ResponseCode::REQUEST_REJECT);
148 GTEST_LOG_(INFO) << "DoCoredumpRequestTest: end.";
149 }
150
151 /**
152 * @tc.name: RecorderProcessMapTest
153 * @tc.desc: RecorderProcessMap
154 * @tc.type: FUNC
155 */
156 HWTEST_F(FaultloggerdClientTest, RecorderProcessMapTest, TestSize.Level2)
157 {
158 GTEST_LOG_(INFO) << "RecorderProcessMapTest: start.";
159 RecorderProcessMap recorderProcessMap;
160 int32_t coredumpSocketId = 0;
161 int32_t processDumpPid = getpid();
162 bool flag = false;
163 EXPECT_FALSE(recorderProcessMap.ClearTargetPid(getpid()));
164 EXPECT_FALSE(recorderProcessMap.SetCancelFlag(getpid(), true));
165 EXPECT_FALSE(recorderProcessMap.SetProcessDumpPid(getpid(), getpid()));
166 EXPECT_FALSE(recorderProcessMap.GetCoredumpSocketId(getpid(), coredumpSocketId));
167 EXPECT_FALSE(recorderProcessMap.GetProcessDumpPid(getpid(), processDumpPid));
168 EXPECT_FALSE(recorderProcessMap.GetCancelFlag(getpid(), flag));
169 GTEST_LOG_(INFO) << "RecorderProcessMapTest: end.";
170 }
171
172 /**
173 * @tc.name: CoreDumpCbTest001
174 * @tc.desc: Test startcoredumpcb and finishcoredumpcb process
175 * @tc.type: FUNC
176 */
177 HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest001, TestSize.Level2)
178 {
179 GTEST_LOG_(INFO) << "CoreDumpCbTest001: start.";
180 int32_t retCode = ResponseCode::REQUEST_SUCCESS;
181 std::string fileName = "com.ohos.sceneboard.dmp";
182 ASSERT_EQ(StartCoredumpCb(getpid(), getpid()), ResponseCode::ABNORMAL_SERVICE);
183 ASSERT_EQ(FinishCoredumpCb(getpid(), fileName, retCode), ResponseCode::REQUEST_SUCCESS);
184 GTEST_LOG_(INFO) << "CoreDumpCbTest001: end.";
185 }
186
187 /**
188 * @tc.name: CoreDumpCbTest002
189 * @tc.desc: Test coredump process
190 * @tc.type: FUNC
191 */
192 HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest002, TestSize.Level2)
193 {
194 GTEST_LOG_(INFO) << "CoreDumpCbTest002: start.";
195 int32_t retCode = ResponseCode::REQUEST_SUCCESS;
196 std::string fileName = "com.ohos.sceneboard.dmp";
197
__anonedb1163c0102() 198 auto threadFunc = [&fileName, retCode]() {
199 sleep(1);
200 StartCoredumpCb(getpid(), getpid());
201 FinishCoredumpCb(getpid(), fileName, retCode);
202 };
203
204 std::thread t(threadFunc);
205 t.detach();
206 auto ret = SaveCoredumpToFileTimeout(getpid());
207 ASSERT_EQ(ret, "com.ohos.sceneboard.dmp");
208 GTEST_LOG_(INFO) << "CoreDumpCbTest002: end.";
209 }
210
211 /**
212 * @tc.name: CoreDumpCbTest003
213 * @tc.desc: Test coredump cancel process
214 * @tc.type: FUNC
215 */
216 HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest003, TestSize.Level2)
217 {
218 GTEST_LOG_(INFO) << "CoreDumpCbTest003: start.";
__anonedb1163c0202() 219 auto threadFunc = []() {
220 sleep(1);
221 ASSERT_EQ(CancelCoredump(getpid()), ResponseCode::REQUEST_SUCCESS);
222 StartCoredumpCb(getpid(), getpid()); // to clean processmap
223 };
224
225 std::thread t(threadFunc);
226 t.detach();
227 auto ret = SaveCoredumpToFileTimeout(getpid());
228 ASSERT_EQ(ret, "");
229 GTEST_LOG_(INFO) << "CoreDumpCbTest003: end.";
230 }
231
232 /**
233 * @tc.name: CoreDumpCbTest004
234 * @tc.desc: Test coredump cancel process
235 * @tc.type: FUNC
236 */
237 HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest004, TestSize.Level2)
238 {
239 GTEST_LOG_(INFO) << "CoreDumpCbTest004: start.";
__anonedb1163c0302() 240 auto threadFunc = []() {
241 sleep(1);
242 StartCoredumpCb(getpid(), getpid());
243 ASSERT_EQ(CancelCoredump(getpid()), ResponseCode::REQUEST_SUCCESS);
244 };
245
246 std::thread t(threadFunc);
247 t.detach();
248 auto ret = SaveCoredumpToFileTimeout(getpid());
249 ASSERT_EQ(ret, "");
250 GTEST_LOG_(INFO) << "CoreDumpCbTest004: end.";
251 }
252
253 /**
254 * @tc.name: CoreDumpCbTest005
255 * @tc.desc: Test coredump cancel process
256 * @tc.type: FUNC
257 */
258 HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest005, TestSize.Level2)
259 {
260 GTEST_LOG_(INFO) << "CoreDumpCbTest005: start.";
261 ASSERT_EQ(CancelCoredump(getpid()), ResponseCode::DEFAULT_ERROR_CODE);
262 GTEST_LOG_(INFO) << "CoreDumpCbTest005: end.";
263 }
264
265 /**
266 * @tc.name: CoreDumpCbTest006
267 * @tc.desc: Test coredump repeat process
268 * @tc.type: FUNC
269 */
270 HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest006, TestSize.Level2)
271 {
272 GTEST_LOG_(INFO) << "CoreDumpCbTest006: start.";
273 int32_t retCode = ResponseCode::REQUEST_SUCCESS;
274 std::string fileName = "com.ohos.sceneboard.dmp";
275
__anonedb1163c0402() 276 auto threadFunc = [&fileName, retCode]() {
277 sleep(1);
278 ASSERT_EQ(SaveCoredumpToFileTimeout(getpid()), "");
279 StartCoredumpCb(getpid(), getpid());
280 FinishCoredumpCb(getpid(), fileName, retCode);
281 };
282
283 std::thread t(threadFunc);
284 t.detach();
285 auto ret = SaveCoredumpToFileTimeout(getpid());
286 ASSERT_EQ(ret, "com.ohos.sceneboard.dmp");
287 GTEST_LOG_(INFO) << "CoreDumpCbTest006: end.";
288 }
289
290 /**
291 * @tc.name: CoreDumpCbTest007
292 * @tc.desc: Test coredump process when targetPid = -1
293 * @tc.type: FUNC
294 */
295 HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest007, TestSize.Level2)
296 {
297 GTEST_LOG_(INFO) << "CoreDumpCbTest007: start.";
298 int32_t targetPid = -1;
299 int32_t retCode = ResponseCode::REQUEST_SUCCESS;
300 std::string fileName = "com.ohos.sceneboard.dmp";
301 ASSERT_EQ(SaveCoredumpToFileTimeout(targetPid), "");
302 ASSERT_EQ(CancelCoredump(targetPid), ResponseCode::DEFAULT_ERROR_CODE);
303 ASSERT_EQ(StartCoredumpCb(targetPid, getpid()), ResponseCode::DEFAULT_ERROR_CODE);
304 ASSERT_EQ(FinishCoredumpCb(targetPid, fileName, retCode), ResponseCode::DEFAULT_ERROR_CODE);
305 GTEST_LOG_(INFO) << "CoreDumpCbTest007: end.";
306 }
307
308 /**
309 * @tc.name: RequestSdkDumpTest001
310 * @tc.desc: test the function for RequestSdkDump.
311 * @tc.type: FUNC
312 */
313 HWTEST_F(FaultloggerdClientTest, RequestSdkDumpTest001, TestSize.Level2)
314 {
315 GTEST_LOG_(INFO) << "RequestSdkDumpTest001: start.";
316 int pipeFds[] = { -1, -1 };
317 ASSERT_EQ(RequestSdkDump(getpid(), gettid(), pipeFds), ResponseCode::REQUEST_SUCCESS);
318 ASSERT_TRUE(pipeFds[0] >= 0);
319 ASSERT_TRUE(pipeFds[1] >= 0);
320 GTEST_LOG_(INFO) << "RequestSdkDumpTest001: end.";
321 }
322
323 /**
324 * @tc.name: RequestFileDescriptorTest001
325 * @tc.desc: test the function for RequestFileDescriptor.
326 * @tc.type: FUNC
327 */
328 HWTEST_F(FaultloggerdClientTest, RequestFileDescriptorTest001, TestSize.Level2)
329 {
330 GTEST_LOG_(INFO) << "RequestFileDescriptorTest001: start.";
331 SmartFd sFd(RequestFileDescriptor(FaultLoggerType::CPP_CRASH));
332 ASSERT_GT(sFd.GetFd(), 0);
333 GTEST_LOG_(INFO) << "RequestFileDescriptorTest001: end.";
334 }
335
336 /**
337 * @tc.name: RequestFileDescriptorTest002
338 * @tc.desc: test the function for RequestFileDescriptor.
339 * @tc.type: FUNC
340 */
341 HWTEST_F(FaultloggerdClientTest, RequestFileDescriptorTest002, TestSize.Level2)
342 {
343 GTEST_LOG_(INFO) << "RequestFileDescriptorTest002: start.";
344 SmartFd sFd(RequestFileDescriptor(FaultLoggerType::FFRT_CRASH_LOG));
345 ASSERT_EQ(sFd.GetFd(), -1);
346 GTEST_LOG_(INFO) << "RequestFileDescriptorTest002: end.";
347 }
348
349 /**
350 * @tc.name: RequestFileDescriptorTest003
351 * @tc.desc: test the function for RequestFileDescriptor.
352 * @tc.type: FUNC
353 */
354 HWTEST_F(FaultloggerdClientTest, RequestFileDescriptorTest003, TestSize.Level2)
355 {
356 GTEST_LOG_(INFO) << "RequestFileDescriptorTest003: start.";
357 SmartFd sFd(RequestFileDescriptor(FaultLoggerType::CJ_HEAP_SNAPSHOT));
358 ASSERT_EQ(sFd.GetFd(), -1);
359 GTEST_LOG_(INFO) << "RequestFileDescriptorTest003: end.";
360 }
361
362 /**
363 * @tc.name: LogFileDesClientTest01
364 * @tc.desc: test the function for RequestFileDescriptorEx.
365 * @tc.type: FUNC
366 */
367 HWTEST_F(FaultloggerdClientTest, RequestFileDescriptorEx001, TestSize.Level2)
368 {
369 GTEST_LOG_(INFO) << "RequestFileDescriptorEx001: start.";
370 FaultLoggerdRequest faultLoggerdRequest;
371 faultLoggerdRequest.type = FaultLoggerType::CPP_CRASH;
372 faultLoggerdRequest.pid = getpid();
373 faultLoggerdRequest.tid = gettid();
374 faultLoggerdRequest.time = GetTimeMilliSeconds();
375 SmartFd sFd(RequestFileDescriptorEx(&faultLoggerdRequest));
376 ASSERT_GE(sFd.GetFd(), 0);
377 GTEST_LOG_(INFO) << "RequestFileDescriptorEx001: end.";
378 }
379
380 /**
381 * @tc.name: RequestFileDescriptorEx002
382 * @tc.desc: test the function for RequestFileDescriptorEx with invalid parameter.
383 * @tc.type: FUNC
384 */
385 HWTEST_F(FaultloggerdClientTest, RequestFileDescriptorEx002, TestSize.Level2)
386 {
387 GTEST_LOG_(INFO) << "RequestFileDescriptorEx002: start.";
388 SmartFd sFd(RequestFileDescriptorEx(nullptr));
389 ASSERT_EQ(sFd.GetFd(), -1);
390 GTEST_LOG_(INFO) << "RequestFileDescriptorEx002: end.";
391 }
392
393 /**
394 * @tc.name: RequestSdkDumpTest002
395 * @tc.desc: test the function for RequestSdkDump.
396 * @tc.type: FUNC
397 */
398 HWTEST_F(FaultloggerdClientTest, RequestSdkDumpTest002, TestSize.Level2)
399 {
400 GTEST_LOG_(INFO) << "RequestSdkDumpTest002: start.";
401 int pipeFds[] = { -1, -1 };
402 ASSERT_EQ(RequestSdkDump(0, 0, pipeFds), -1);
403 ASSERT_EQ(RequestSdkDump(1, -1, pipeFds), -1);
404 ASSERT_EQ(RequestSdkDump(getpid(), gettid(), pipeFds), ResponseCode::SDK_PROCESS_CRASHED);
405 GTEST_LOG_(INFO) << "RequestSdkDumpTest002: end.";
406 }
407
408 /**
409 * @tc.name: RequestPipeFdTest001
410 * @tc.desc: test the function for RequestPipeFd.
411 * @tc.type: FUNC
412 */
413 HWTEST_F(FaultloggerdClientTest, RequestPipeFdTest001, TestSize.Level2)
414 {
415 GTEST_LOG_(INFO) << "RequestPipeFd001: start.";
416 int pipeFds[] = { -1, -1 };
417 ASSERT_EQ(RequestPipeFd(0, PIPE_FD_READ - 1, pipeFds), -1);
418 ASSERT_EQ(RequestPipeFd(0, PIPE_FD_DELETE + 1, pipeFds), -1);
419 ASSERT_EQ(RequestPipeFd(getpid(), PIPE_FD_READ, pipeFds), ResponseCode::REQUEST_SUCCESS);
420 SmartFd buffFd{pipeFds[0]};
421 SmartFd resFd{pipeFds[1]};
422 ASSERT_GE(buffFd.GetFd(), 0);
423 ASSERT_GE(resFd.GetFd(), 0);
424 GTEST_LOG_(INFO) << "RequestPipeFd001: end.";
425 }
426
427 /**
428 * @tc.name: RequestDelPipeFdTest001
429 * @tc.desc: test the function for RequestDelPipeFd.
430 * @tc.type: FUNC
431 */
432 HWTEST_F(FaultloggerdClientTest, RequestDelPipeFdTest001, TestSize.Level2)
433 {
434 GTEST_LOG_(INFO) << "FaultloggerdClientTest001: start.";
435 ASSERT_EQ(RequestDelPipeFd(getpid()), ResponseCode::REQUEST_SUCCESS);
436 GTEST_LOG_(INFO) << "FaultloggerdClientTest001: end.";
437 }
438
439 /**
440 * @tc.name: ReportDumpStatsTest001
441 * @tc.desc: test the function for ReportDumpStats.
442 * @tc.type: FUNC
443 */
444 HWTEST_F(FaultloggerdClientTest, ReportDumpStatsTest001, TestSize.Level2)
445 {
446 GTEST_LOG_(INFO) << "FaultloggerdClientTest001: start.";
447 ASSERT_EQ(ReportDumpStats(nullptr), -1);
448 FaultLoggerdStatsRequest request;
449 ASSERT_EQ(ReportDumpStats(&request), 0);
450 GTEST_LOG_(INFO) << "FaultloggerdClientTest001: end.";
451 }
452 } // namespace HiviewDFX
453 } // namepsace OHOS
454