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 <gtest/gtest.h>
17
18#include <securec.h>
19#ifndef is_ohos_lite
20#include "gmock/gmock.h"
21#endif
22#include <sys/socket.h>
23#include <sys/un.h>
24#include <unistd.h>
25#include "dfx_exception.h"
26#include "dfx_util.h"
27#include "faultloggerd_client.h"
28#include "faultloggerd_socket.h"
29#include "fault_logger_config.h"
30#include "fault_logger_daemon.h"
31#include "fault_logger_pipe.h"
32
33using namespace OHOS::HiviewDFX;
34using namespace testing::ext;
35using namespace std;
36
37namespace OHOS {
38namespace HiviewDFX {
39class FaultLoggerDaemonTest : public testing::Test {
40public:
41    static void SetUpTestCase(void) {}
42    static void TearDownTestCase(void) {}
43    void SetUp() {}
44    void TearDown() {}
45};
46
47#ifndef is_ohos_lite
48class MockFaultLoggerDaemon : public FaultLoggerDaemon {
49public:
50    MOCK_METHOD(bool, CreateSockets, (), (override));
51    MOCK_METHOD(bool, InitEnvironment, (), (override));
52    MOCK_METHOD(bool, CreateEventFd, (), (override));
53    MOCK_METHOD(void, WaitForRequest, (), (override));
54};
55#endif
56} // namespace HiviewDFX
57} // namespace OHOS
58
59namespace {
60constexpr int32_t FAULTLOGGERD_FUZZ_READ_BUFF = 1024;
61static constexpr uint32_t ROOT_UID = 0;
62static constexpr uint32_t BMS_UID = 1000;
63static constexpr uint32_t HIVIEW_UID = 1201;
64static constexpr uint32_t HIDUMPER_SERVICE_UID = 1212;
65static constexpr uint32_t FOUNDATION_UID = 5523;
66static constexpr uint32_t PIPE_TYPE_COUNT = 8;
67
68/**
69 * @tc.name: FaultLoggerDaemonTest001
70 * @tc.desc: test HandleDefaultClientRequest/HandleLogFileDesClientRequest func
71 * @tc.type: FUNC
72 */
73HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest001, TestSize.Level2)
74{
75    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest001: start.";
76    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
77    bool ret = daemon->InitEnvironment();
78    ASSERT_TRUE(ret);
79    struct FaultLoggerdRequest faultloggerdRequest;
80    if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) {
81        GTEST_LOG_(ERROR) << "memset_s failed" ;
82        ASSERT_TRUE(false);
83    }
84    faultloggerdRequest.type = 0;
85    faultloggerdRequest.pid = getpid();
86    faultloggerdRequest.tid = gettid();
87    faultloggerdRequest.uid = getuid();
88    daemon->HandleDefaultClientRequest(-1, &faultloggerdRequest);
89    faultloggerdRequest.type = 2; // 2 : CPP_CRASH
90    daemon->HandleDefaultClientRequest(-1, &faultloggerdRequest);
91    daemon->HandleLogFileDesClientRequest(-1, &faultloggerdRequest);
92    faultloggerdRequest.type = 101; // 101 : CPP_STACKTRACE
93    daemon->HandleDefaultClientRequest(-1, &faultloggerdRequest);
94    faultloggerdRequest.type = 102; // 102 : JS_STACKTRACE
95    daemon->HandleDefaultClientRequest(-1, &faultloggerdRequest);
96    faultloggerdRequest.type = 103; // 103 : JS_HEAP_SNAPSHOT
97    daemon->HandleDefaultClientRequest(-1, &faultloggerdRequest);
98    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest001: end.";
99}
100
101/**
102 * @tc.name: FaultLoggerDaemonTest002
103 * @tc.desc: test HandleSdkDumpRequest/HandlePipeFdClientRequest func
104 * @tc.type: FUNC
105 */
106HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest002, TestSize.Level2)
107{
108    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest002: start.";
109    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
110    bool ret = daemon->InitEnvironment();
111    ASSERT_TRUE(ret);
112    struct FaultLoggerdRequest faultloggerdRequest;
113    if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) {
114        GTEST_LOG_(ERROR) << "memset_s failed" ;
115        ASSERT_TRUE(false);
116    }
117    faultloggerdRequest.type = 2; // 2 : CPP_CRASH
118    faultloggerdRequest.pid = getpid();
119    faultloggerdRequest.tid = gettid();
120    faultloggerdRequest.uid = getuid();
121    daemon->HandleSdkDumpRequest(-1, &faultloggerdRequest);
122    faultloggerdRequest.pipeType = FaultLoggerPipeType::PIPE_FD_READ_BUF;
123    daemon->HandlePipeFdClientRequest(-1, &faultloggerdRequest);
124    faultloggerdRequest.pipeType = FaultLoggerPipeType::PIPE_FD_WRITE_BUF;
125    daemon->HandlePipeFdClientRequest(-1, &faultloggerdRequest);
126    faultloggerdRequest.pipeType = FaultLoggerPipeType::PIPE_FD_READ_RES;
127    daemon->HandlePipeFdClientRequest(-1, &faultloggerdRequest);
128    faultloggerdRequest.pipeType = FaultLoggerPipeType::PIPE_FD_WRITE_RES;
129    daemon->HandlePipeFdClientRequest(-1, &faultloggerdRequest);
130    faultloggerdRequest.pipeType = FaultLoggerPipeType::PIPE_FD_DELETE;
131    daemon->HandlePipeFdClientRequest(-1, &faultloggerdRequest);
132    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest002: end.";
133}
134
135/**
136 * @tc.name: FaultLoggerDaemonTest003
137 * @tc.desc: test HandleSdkDumpRequest func
138 * @tc.type: FUNC
139 */
140HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest003, TestSize.Level2)
141{
142    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest003: start.";
143    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
144    bool ret = daemon->InitEnvironment();
145    ASSERT_TRUE(ret);
146    struct FaultLoggerdRequest faultloggerdRequest;
147    if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) {
148        GTEST_LOG_(ERROR) << "memset_s failed" ;
149        ASSERT_TRUE(false);
150    }
151    faultloggerdRequest.type = 2; // 2 : CPP_CRASH
152    faultloggerdRequest.pid = getpid();
153    faultloggerdRequest.tid = gettid();
154    faultloggerdRequest.uid = getuid();
155    daemon->HandleSdkDumpRequest(-1, &faultloggerdRequest);
156    faultloggerdRequest.tid = 0;
157    daemon->HandleSdkDumpRequest(-1, &faultloggerdRequest);
158    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest003: end.";
159}
160
161/**
162 * @tc.name: FaultLoggerDaemonTest004
163 * @tc.desc: test CreateFileForRequest func
164 * @tc.type: FUNC
165 */
166HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest004, TestSize.Level2)
167{
168    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest004: start.";
169    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
170    int32_t type = (int32_t)FaultLoggerType::CPP_CRASH;
171    int32_t pid = getpid();
172    uint64_t time = GetTimeMilliSeconds();
173    int fd = daemon->CreateFileForRequest(type, pid, 0, time);
174    ASSERT_NE(fd, -1);
175    close(fd);
176    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest004: end.";
177}
178
179/**
180 * @tc.name: FaultLoggerDaemonTest005
181 * @tc.desc: test CreateFileForRequest JIT_CODE_LOG and FFRT_CRASH_LOG branch
182 * @tc.type: FUNC
183 */
184HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest005, TestSize.Level2)
185{
186    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest005: start.";
187    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
188    bool ret = daemon->InitEnvironment();
189    ASSERT_TRUE(ret);
190
191    int32_t pid = getpid();
192    uint64_t time = GetTimeMilliSeconds();
193    int32_t type = static_cast<int32_t>(FaultLoggerType::JIT_CODE_LOG);
194    int fd = daemon->CreateFileForRequest(type, pid, 0, time);
195    ASSERT_NE(fd, -1);
196    type = static_cast<int32_t>(FaultLoggerType::FFRT_CRASH_LOG);
197    fd = daemon->CreateFileForRequest(type, pid, 0, time);
198    ASSERT_NE(fd, -1);
199    close(fd);
200    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest005: end.";
201}
202
203void DoClientProcess(const std::string& socketFileName)
204{
205    sleep(2); // 2 : wait 2 seconds, waiting for the service to be ready
206    int clientSocketFd = -1;
207    bool ret = StartConnect(clientSocketFd, socketFileName.c_str(), 10); // 10 : socket connect time out 10 second
208    ASSERT_TRUE(ret);
209    ASSERT_NE(clientSocketFd, -1);
210    GTEST_LOG_(INFO) << "child connect finished, client fd:" << clientSocketFd;
211
212    int data = 12345; // 12345 is for server Cred test
213    ret = SendMsgIovToSocket(clientSocketFd, reinterpret_cast<void *>(&data), sizeof(data));
214    ASSERT_TRUE(ret);
215
216    GTEST_LOG_(INFO) << "Start read file desc";
217    int testFd = ReadFileDescriptorFromSocket(clientSocketFd);
218    GTEST_LOG_(INFO) << "recv testFd:" << testFd;
219    ASSERT_NE(testFd, -1);
220    close(clientSocketFd);
221    close(testFd);
222}
223
224void TestSecurityCheck(const std::string& socketFileName)
225{
226    int32_t serverSocketFd = -1;
227    bool ret = StartListen(serverSocketFd, socketFileName.c_str(), 5); // 5: means max connection count is 5
228    ASSERT_TRUE(ret);
229    ASSERT_NE(serverSocketFd, -1);
230    GTEST_LOG_(INFO) << "server start listen fd:" << serverSocketFd;
231
232    struct timeval timev = {
233        20, // 20 : recv timeout 20 seconds
234        0
235    };
236    void* pTimev = &timev;
237    int retOpt = OHOS_TEMP_FAILURE_RETRY(setsockopt(serverSocketFd, SOL_SOCKET, SO_RCVTIMEO,
238        static_cast<const char*>(pTimev), sizeof(struct timeval)));
239    ASSERT_NE(retOpt, -1);
240
241    struct sockaddr_un clientAddr;
242    socklen_t clientAddrSize = static_cast<socklen_t>(sizeof(clientAddr));
243    int32_t connectionFd = OHOS_TEMP_FAILURE_RETRY(accept(serverSocketFd,
244        reinterpret_cast<struct sockaddr *>(&clientAddr), &clientAddrSize));
245    ASSERT_GT(connectionFd, 0);
246
247    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
248    struct FaultLoggerdRequest faultloggerdRequest;
249    if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) {
250        GTEST_LOG_(ERROR) << "memset_s failed" ;
251        ASSERT_TRUE(false);
252    }
253    faultloggerdRequest.type = 2; // 2 : CPP_CRASH
254    faultloggerdRequest.pid = getpid();
255    faultloggerdRequest.tid = gettid();
256    faultloggerdRequest.uid = getuid();
257
258    FaultLoggerCheckPermissionResp resp = daemon->SecurityCheck(connectionFd, &faultloggerdRequest);
259    ASSERT_EQ(resp, FaultLoggerCheckPermissionResp::CHECK_PERMISSION_REJECT);
260
261    close(connectionFd);
262    close(serverSocketFd);
263}
264
265/**
266 * @tc.name: FaultLoggerDaemonTest006
267 * @tc.desc: test SecurityCheck abnormal branch
268 * @tc.type: FUNC
269 */
270HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest006, TestSize.Level2)
271{
272    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest006: start.";
273    std::string testSocketName = "faultloggerd.server.test";
274    int32_t pid = fork();
275    if (pid == 0) {
276        DoClientProcess(testSocketName);
277        GTEST_LOG_(INFO) << "client exit";
278        exit(0);
279    } else if (pid > 0) {
280        TestSecurityCheck(testSocketName);
281
282        int status;
283        bool isSuccess = waitpid(pid, &status, 0) != -1;
284        if (!isSuccess) {
285            ASSERT_FALSE(isSuccess);
286            return;
287        }
288
289        int exitCode = -1;
290        if (WIFEXITED(status)) {
291            exitCode = WEXITSTATUS(status);
292            GTEST_LOG_(INFO) << "Exit status was " << exitCode;
293        }
294        ASSERT_EQ(exitCode, 0);
295    }
296    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest006: end.";
297}
298
299void TestCheckRequestCredential(const std::string& socketFileName)
300{
301    int32_t serverSocketFd = -1;
302    bool ret = StartListen(serverSocketFd, socketFileName.c_str(), 5); // 5: means max connection count is 5
303    ASSERT_TRUE(ret);
304    ASSERT_NE(serverSocketFd, -1);
305    GTEST_LOG_(INFO) << "server start listen fd:" << serverSocketFd;
306
307    struct timeval timev = {
308        20, // 20 : recv timeout 20 seconds
309        0
310    };
311    void* pTimev = &timev;
312    int retOpt = OHOS_TEMP_FAILURE_RETRY(setsockopt(serverSocketFd, SOL_SOCKET, SO_RCVTIMEO,
313        static_cast<const char*>(pTimev), sizeof(struct timeval)));
314    ASSERT_NE(retOpt, -1);
315
316    struct sockaddr_un clientAddr;
317    socklen_t clientAddrSize = static_cast<socklen_t>(sizeof(clientAddr));
318    int32_t connectionFd = OHOS_TEMP_FAILURE_RETRY(accept(serverSocketFd,
319        reinterpret_cast<struct sockaddr *>(&clientAddr), &clientAddrSize));
320    ASSERT_GT(connectionFd, 0);
321
322    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
323    struct FaultLoggerdRequest faultloggerdRequest;
324    if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) {
325        GTEST_LOG_(ERROR) << "memset_s failed" ;
326        ASSERT_TRUE(false);
327    }
328    faultloggerdRequest.type = 2; // 2 : CPP_CRASH
329    faultloggerdRequest.pid = getpid();
330    faultloggerdRequest.tid = gettid();
331    faultloggerdRequest.uid = getuid();
332
333    bool result = daemon->CheckRequestCredential(connectionFd, nullptr);
334    ASSERT_EQ(result, false);
335    result = daemon->CheckRequestCredential(connectionFd, &faultloggerdRequest);
336    ASSERT_EQ(result, false);
337
338    close(connectionFd);
339    close(serverSocketFd);
340}
341
342/**
343 * @tc.name: FaultLoggerDaemonTest007
344 * @tc.desc: test CheckRequestCredential abnormal branch
345 * @tc.type: FUNC
346 */
347HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest007, TestSize.Level2)
348{
349    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest007: start.";
350    std::string testSocketName = "faultloggerd.server.test";
351    int32_t pid = fork();
352    if (pid == 0) {
353        DoClientProcess(testSocketName);
354        GTEST_LOG_(INFO) << "client exit";
355        exit(0);
356    } else if (pid > 0) {
357        TestCheckRequestCredential(testSocketName);
358
359        int status;
360        bool isSuccess = waitpid(pid, &status, 0) != -1;
361        if (!isSuccess) {
362            ASSERT_FALSE(isSuccess);
363            return;
364        }
365
366        int exitCode = -1;
367        if (WIFEXITED(status)) {
368            exitCode = WEXITSTATUS(status);
369            GTEST_LOG_(INFO) << "Exit status was " << exitCode;
370        }
371        ASSERT_EQ(exitCode, 0);
372    }
373    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest007: end.";
374}
375
376void TestHandleExceptionRequest(const std::string& socketFileName)
377{
378    int32_t serverSocketFd = -1;
379    bool ret = StartListen(serverSocketFd, socketFileName.c_str(), 5); // 5: means max connection count is 5
380    ASSERT_TRUE(ret);
381    ASSERT_NE(serverSocketFd, -1);
382    GTEST_LOG_(INFO) << "server start listen fd:" << serverSocketFd;
383
384    struct timeval timev = {
385        20, // 20 : recv timeout 20 seconds
386        0
387    };
388    void* pTimev = &timev;
389    int retOpt = OHOS_TEMP_FAILURE_RETRY(setsockopt(serverSocketFd, SOL_SOCKET, SO_RCVTIMEO,
390        static_cast<const char*>(pTimev), sizeof(struct timeval)));
391    ASSERT_NE(retOpt, -1);
392
393    struct sockaddr_un clientAddr;
394    socklen_t clientAddrSize = static_cast<socklen_t>(sizeof(clientAddr));
395    int32_t connectionFd = OHOS_TEMP_FAILURE_RETRY(accept(serverSocketFd,
396        reinterpret_cast<struct sockaddr *>(&clientAddr), &clientAddrSize));
397    ASSERT_GT(connectionFd, 0);
398
399    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
400    struct FaultLoggerdRequest faultloggerdRequest;
401    if (memset_s(&faultloggerdRequest, sizeof(faultloggerdRequest), 0, sizeof(struct FaultLoggerdRequest)) != 0) {
402        GTEST_LOG_(ERROR) << "memset_s failed" ;
403        ASSERT_TRUE(false);
404    }
405    faultloggerdRequest.type = 2; // 2 : CPP_CRASH
406    faultloggerdRequest.pid = getpid();
407    faultloggerdRequest.tid = gettid();
408    faultloggerdRequest.uid = getuid();
409
410    daemon->HandleExceptionRequest(connectionFd, &faultloggerdRequest);
411
412    close(connectionFd);
413    close(serverSocketFd);
414}
415
416/**
417 * @tc.name: FaultLoggerDaemonTest008
418 * @tc.desc: test HandleExceptionRequest abnormal branch
419 * @tc.type: FUNC
420 */
421HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest008, TestSize.Level2)
422{
423    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest008: start.";
424    std::string testSocketName = "faultloggerd.server.test";
425    int32_t pid = fork();
426    if (pid == 0) {
427        DoClientProcess(testSocketName);
428        GTEST_LOG_(INFO) << "client exit";
429        exit(0);
430    } else if (pid > 0) {
431        TestHandleExceptionRequest(testSocketName);
432
433        int status;
434        bool isSuccess = waitpid(pid, &status, 0) != -1;
435        if (!isSuccess) {
436            ASSERT_FALSE(isSuccess);
437            return;
438        }
439
440        int exitCode = -1;
441        if (WIFEXITED(status)) {
442            exitCode = WEXITSTATUS(status);
443            GTEST_LOG_(INFO) << "Exit status was " << exitCode;
444        }
445        ASSERT_EQ(exitCode, 0);
446    }
447    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest008: end.";
448}
449
450/**
451 * @tc.name: FaultLoggerDaemonTest009
452 * @tc.desc: test HandleAccept abnormal branch
453 * @tc.type: FUNC
454 */
455HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest009, TestSize.Level2)
456{
457    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest009: start.";
458    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
459    bool ret = daemon->InitEnvironment();
460    ASSERT_TRUE(ret);
461    daemon->HandleAccept(1, 1);
462    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest009: end.";
463}
464
465/**
466 * @tc.name: FaultLoggerDaemonTest010
467 * @tc.desc: test HandleRequestByClientType abnormal branch
468 * @tc.type: FUNC
469 */
470HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest010, TestSize.Level2)
471{
472    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest010: start.";
473    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
474    bool ret = daemon->InitEnvironment();
475    ASSERT_TRUE(ret);
476
477    int32_t connectionFd = 1;
478
479    FaultLoggerdRequest request;
480    request.clientType = FaultLoggerClientType::DEFAULT_CLIENT;
481    daemon->HandleRequestByClientType(connectionFd, &request);
482    request.clientType = FaultLoggerClientType::LOG_FILE_DES_CLIENT;
483    daemon->HandleRequestByClientType(connectionFd, &request);
484    request.clientType = FaultLoggerClientType::PRINT_T_HILOG_CLIENT;
485    daemon->HandleRequestByClientType(connectionFd, &request);
486    request.clientType = FaultLoggerClientType::PERMISSION_CLIENT;
487    daemon->HandleRequestByClientType(connectionFd, &request);
488    request.clientType = FaultLoggerClientType::PIPE_FD_CLIENT;
489    daemon->HandleRequestByClientType(connectionFd, &request);
490    request.clientType = FaultLoggerClientType::SDK_DUMP_CLIENT;
491    daemon->HandleRequestByClientType(connectionFd, &request);
492    request.clientType = FaultLoggerClientType::REPORT_EXCEPTION_CLIENT;
493    daemon->HandleRequestByClientType(connectionFd, &request);
494    request.clientType = -1;
495    daemon->HandleRequestByClientType(connectionFd, &request);
496    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest010: end.";
497}
498
499void TestHandleRequestByPipeType(std::shared_ptr<FaultLoggerDaemon> daemon, FaultLoggerPipe2* faultLoggerPipe,
500    FaultLoggerdRequest request, int32_t pipeType, bool isChangeFd)
501{
502    int fd = -1;
503    request.pipeType = pipeType;
504    daemon->HandleRequestByPipeType(fd, 1, &request, faultLoggerPipe);
505    if (isChangeFd) {
506        ASSERT_NE(fd, -1);
507    } else {
508        ASSERT_EQ(fd, -1);
509    }
510}
511
512/**
513 * @tc.name: FaultLoggerDaemonTest011
514 * @tc.desc: test HandleRequestByPipeType abnormal branch
515 * @tc.type: FUNC
516 */
517HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest011, TestSize.Level2)
518{
519    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest011: start.";
520    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
521    bool ret = daemon->InitEnvironment();
522    ASSERT_TRUE(ret);
523
524    FaultLoggerdRequest request;
525    FaultLoggerPipe2* faultLoggerPipe = new FaultLoggerPipe2(GetTimeMilliSeconds());
526    bool isChangeFds4Pipe[PIPE_TYPE_COUNT] = {false, true, false, true, false, false, false, false};
527    for (int i = 0; i < PIPE_TYPE_COUNT; i++) {
528        TestHandleRequestByPipeType(daemon, faultLoggerPipe, request, i, isChangeFds4Pipe[i]);
529    }
530    delete(faultLoggerPipe);
531
532    FaultLoggerPipe2* faultLoggerJsonPipe = new FaultLoggerPipe2(GetTimeMilliSeconds(), true);
533    bool isChangeFds4JsonPipe[PIPE_TYPE_COUNT] = {false, false, false, false, false, true, false, true};
534    for (int i = 0; i < PIPE_TYPE_COUNT; i++) {
535        TestHandleRequestByPipeType(daemon, faultLoggerJsonPipe, request, i, isChangeFds4JsonPipe[i]);
536    }
537    delete(faultLoggerJsonPipe);
538    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest011: end.";
539}
540
541#ifndef is_ohos_lite
542/**
543 * @tc.name: FaultLoggerDaemonTest012
544 * @tc.desc: test FaultLoggerDaemon HandleStaticForFuzzer
545 * @tc.type: FUNC
546 */
547HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest012, TestSize.Level2)
548{
549    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
550    int params[][2] = {
551        {FaultLoggerType::CPP_STACKTRACE, ROOT_UID},
552        {FaultLoggerType::JS_STACKTRACE, BMS_UID},
553        {FaultLoggerType::LEAK_STACKTRACE, HIVIEW_UID},
554        {FaultLoggerType::FFRT_CRASH_LOG, HIDUMPER_SERVICE_UID},
555        {FaultLoggerType::JIT_CODE_LOG, FOUNDATION_UID},
556        {FaultLoggerType::JS_HEAP_LEAK_LIST, FOUNDATION_UID},
557    };
558    bool ret = false;
559    for (int i = 0; i < sizeof(params) / sizeof(params[0]); i++) {
560        ret = daemon->HandleStaticForFuzzer(params[i][0], params[i][1]);
561        EXPECT_TRUE(ret);
562    }
563    ret = daemon->HandleStaticForFuzzer(-1, 1);
564    EXPECT_FALSE(ret);
565    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest012: end.";
566}
567
568/**
569 * @tc.name: FaultLoggerDaemonTest013
570 * @tc.desc: test FaultLoggerDaemon StartServer and AddEvent
571 * @tc.type: FUNC
572 */
573HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest013, TestSize.Level2)
574{
575    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest013: start.";
576    MockFaultLoggerDaemon mockDaemon;
577
578    EXPECT_CALL(mockDaemon, CreateSockets()).WillOnce(testing::Return(false));
579    EXPECT_EQ(mockDaemon.StartServer(), -1);
580    EXPECT_CALL(mockDaemon, CreateSockets()).WillOnce(testing::Return(true));
581    EXPECT_CALL(mockDaemon, InitEnvironment()).WillOnce(testing::Return(false));
582    EXPECT_EQ(mockDaemon.StartServer(), -1);
583    EXPECT_CALL(mockDaemon, CreateSockets()).WillOnce(testing::Return(true));
584    EXPECT_CALL(mockDaemon, InitEnvironment()).WillOnce(testing::Return(true));
585    EXPECT_CALL(mockDaemon, CreateEventFd()).WillOnce(testing::Return(false));
586    EXPECT_EQ(mockDaemon.StartServer(), -1);
587    EXPECT_CALL(mockDaemon, CreateSockets()).WillOnce(testing::Return(true));
588    EXPECT_CALL(mockDaemon, InitEnvironment()).WillOnce(testing::Return(true));
589    EXPECT_CALL(mockDaemon, CreateEventFd()).WillOnce(testing::Return(true));
590    EXPECT_CALL(mockDaemon, WaitForRequest()).WillOnce(testing::Return());
591    EXPECT_EQ(mockDaemon.StartServer(), 0);
592
593    FaultLoggerDaemon daemon;
594    EXPECT_EQ(daemon.InitEnvironment(), true);
595    EXPECT_EQ(daemon.CreateEventFd(), true);
596    daemon.CleanupEventFd();
597    daemon.CleanupSockets();
598    daemon.AddEvent(1, 1, 1);
599    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest013: end.";
600}
601#endif
602
603bool CheckReadResp(int sockfd)
604{
605    char controlBuffer[SOCKET_BUFFER_SIZE] = {0};
606    ssize_t nread = OHOS_TEMP_FAILURE_RETRY(read(sockfd, controlBuffer, sizeof(controlBuffer) - 1));
607    if (nread != static_cast<ssize_t>(strlen(FAULTLOGGER_DAEMON_RESP))) {
608        return false;
609    }
610    return true;
611}
612
613void HandleRequestByPipeTypeCommon(std::shared_ptr<FaultLoggerDaemon> daemon, int32_t pipeType,
614    bool isPassCheck = false, bool isJson = false, bool isChangeFd = false)
615{
616    int fd = -1;
617    FaultLoggerdRequest request;
618    request.pipeType = pipeType;
619    std::unique_ptr<FaultLoggerPipe2> ptr = std::make_unique<FaultLoggerPipe2>(GetTimeMilliSeconds(), isJson);
620
621    if (!isPassCheck) {
622        daemon->HandleRequestByPipeType(fd, 1, &request, ptr.get());
623        if (!isChangeFd) {
624            EXPECT_EQ(fd, -1);
625        } else {
626            EXPECT_NE(fd, -1);
627        }
628        close(fd);
629        return;
630    }
631
632    int socketFd[2]; // 2 : the length of the array
633    if (socketpair(AF_UNIX, SOCK_STREAM, 0, socketFd) == 0) {
634        pid_t pid = fork();
635        if (pid == 0) {
636            sleep(1);
637            if (CheckReadResp(socketFd[1])) {
638                std::string test = "test";
639                OHOS_TEMP_FAILURE_RETRY(write(socketFd[1], test.c_str(), sizeof(test)));
640            }
641        } else if (pid > 0) {
642            daemon->connectionMap_[socketFd[0]] = socketFd[0];
643            daemon->HandleRequestByPipeType(fd, socketFd[0], &request, ptr.get());
644            if (!isChangeFd) {
645                EXPECT_EQ(fd, -1);
646            } else {
647                EXPECT_NE(fd, -1);
648            }
649            close(fd);
650            close(socketFd[1]);
651        }
652    }
653}
654
655/**
656 * @tc.name: FaultLoggerDaemonTest014
657 * @tc.desc: test FaultLoggerDaemon for HandleRequestByPipeType
658 * @tc.type: FUNC
659 */
660HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest014, TestSize.Level4)
661{
662    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest014: start.";
663    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
664    daemon->InitEnvironment();
665    HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_READ_BUF, true, false, true);
666    sleep(2);
667    HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_READ_RES, true, false, true);
668    sleep(2);
669    HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_JSON_READ_BUF, true, true, true);
670    sleep(2);
671    HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_JSON_READ_RES, true, true, true);
672    sleep(2);
673    HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_READ_BUF, false, false, false);
674    HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_WRITE_BUF, false, false, true);
675    HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_READ_RES, false, false, false);
676    HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_WRITE_RES, false, false, true);
677    HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_JSON_READ_BUF, false, true, false);
678    HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_JSON_WRITE_BUF, false, true, true);
679    HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_JSON_READ_RES, false, true, false);
680    HandleRequestByPipeTypeCommon(daemon, FaultLoggerPipeType::PIPE_FD_JSON_WRITE_RES, false, true, true);
681    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest014: end.";
682}
683
684void HandleRequestTestCommon(std::shared_ptr<FaultLoggerDaemon> daemon, char* buff, size_t len,
685    void *(*startRoutine)(void *))
686{
687    int socketFd[2]; // 2 : the length of the array
688    if (socketpair(AF_UNIX, SOCK_STREAM, 0, socketFd) == 0) {
689        OHOS_TEMP_FAILURE_RETRY(write(socketFd[1], buff, len));
690        daemon->connectionMap_[socketFd[0]] = socketFd[0];
691
692        if (!startRoutine) {
693            daemon->HandleRequest(0, socketFd[0]);
694        } else {
695            pthread_t threadId;
696            if (pthread_create(&threadId, nullptr, startRoutine, reinterpret_cast<void*>(socketFd[1])) != 0) {
697                perror("Failed to create thread");
698                close(socketFd[0]);
699                close(socketFd[1]);
700                return;
701            }
702
703            daemon->HandleRequest(0, socketFd[0]);
704            EXPECT_NE(socketFd[0], -1);
705
706            pthread_join(threadId, nullptr);
707        }
708        close(socketFd[1]);
709    }
710}
711
712void HandleRequestByClientTypeForDefaultClientTest(std::shared_ptr<FaultLoggerDaemon> daemon)
713{
714    FaultLoggerdRequest requst;
715    requst.clientType = FaultLoggerClientType::DEFAULT_CLIENT;
716    HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr);
717    requst.type = FaultLoggerType::CPP_CRASH;
718    HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr);
719    requst.type = FaultLoggerType::JS_HEAP_SNAPSHOT;
720    HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr);
721    daemon->crashTimeMap_[1] = time(nullptr) - 10; // 10 : Get the first 10 seconds of the current time
722    HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr);
723    daemon->crashTimeMap_[1] = time(nullptr);
724    HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr);
725}
726
727void *ReadThread1(void *param)
728{
729    long fd = reinterpret_cast<long>(param);
730    char buff[FAULTLOGGERD_FUZZ_READ_BUFF];
731    OHOS_TEMP_FAILURE_RETRY(read(fd, buff, sizeof(buff)));
732    char msg[] = "any test str";
733    OHOS_TEMP_FAILURE_RETRY(write(fd, reinterpret_cast<char*>(msg), sizeof(msg)));
734    return nullptr;
735}
736
737void *ReadThread2(void *param)
738{
739    long fd = reinterpret_cast<long>(param);
740    char buff[FAULTLOGGERD_FUZZ_READ_BUFF];
741    OHOS_TEMP_FAILURE_RETRY(read(fd, buff, sizeof(buff)));
742    CrashDumpException test;
743    test.error = CRASH_DUMP_LOCAL_REPORT;
744    OHOS_TEMP_FAILURE_RETRY(write(fd, reinterpret_cast<char*>(&test), sizeof(CrashDumpException)));
745    return nullptr;
746}
747
748void *ReadThread3(void *param)
749{
750    long fd = reinterpret_cast<long>(param);
751    char buff[FAULTLOGGERD_FUZZ_READ_BUFF];
752    OHOS_TEMP_FAILURE_RETRY(read(fd, buff, sizeof(buff)));
753    CrashDumpException test{};
754    OHOS_TEMP_FAILURE_RETRY(write(fd, reinterpret_cast<char*>(&test), sizeof(CrashDumpException)));
755    return nullptr;
756}
757
758void HandleRequestByClientTypeTest(std::shared_ptr<FaultLoggerDaemon> daemon)
759{
760    {
761        FaultLoggerdRequest requst;
762        requst.clientType = FaultLoggerClientType::LOG_FILE_DES_CLIENT;
763        HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr);
764    }
765    {
766        FaultLoggerdRequest requst;
767        requst.clientType = FaultLoggerClientType::PRINT_T_HILOG_CLIENT;
768        HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), ReadThread2);
769    }
770    {
771        FaultLoggerdRequest requst;
772        requst.clientType = FaultLoggerClientType::PERMISSION_CLIENT;
773        HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), ReadThread2);
774    }
775    {
776        FaultLoggerdRequest requst;
777        requst.clientType = FaultLoggerClientType::SDK_DUMP_CLIENT;
778        requst.pid = 1;
779        HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), ReadThread2);
780    }
781    {
782        FaultLoggerdRequest requst;
783        requst.clientType = FaultLoggerClientType::PIPE_FD_CLIENT;
784        HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr);
785    }
786    {
787        FaultLoggerdRequest requst;
788        requst.clientType = FaultLoggerClientType::REPORT_EXCEPTION_CLIENT;
789        HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), ReadThread1);
790        HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), ReadThread2);
791        HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), ReadThread3);
792    }
793    {
794        FaultLoggerdRequest requst;
795        requst.clientType = -1;
796        HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest), nullptr);
797    }
798}
799
800/**
801 * @tc.name: FaultLoggerDaemonTest015
802 * @tc.desc: test FaultLoggerDaemon for HandleRequest
803 * @tc.type: FUNC
804 */
805HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest015, TestSize.Level4)
806{
807    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest015: start.";
808    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
809    {
810        int32_t epollFd = 1;
811        int32_t connectionFd = 4; // 4 : simulate an fd greater than 3
812        daemon->HandleRequest(epollFd, connectionFd);
813        connectionFd = 2;
814        daemon->HandleRequest(epollFd, connectionFd);
815        EXPECT_EQ(epollFd, 1);
816        epollFd = -1;
817        daemon->HandleRequest(epollFd, connectionFd);
818        EXPECT_EQ(epollFd, -1);
819        connectionFd = 4;
820        daemon->HandleRequest(epollFd, connectionFd);
821        EXPECT_EQ(epollFd, -1);
822    }
823    {
824        int socketFd[2]; // 2 : the length of the array
825        if (socketpair(AF_UNIX, SOCK_STREAM, 0, socketFd) == 0) {
826            close(socketFd[1]);
827            daemon->HandleRequest(0, socketFd[0]);
828        }
829    }
830    {
831        FaultLoggerdRequest requst;
832        int socketFd[2]; // 2 : the length of the array
833        if (socketpair(AF_UNIX, SOCK_STREAM, 0, socketFd) == 0) {
834            OHOS_TEMP_FAILURE_RETRY(write(socketFd[1], reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdRequest)));
835            daemon->HandleRequest(0, socketFd[0]);
836            close(socketFd[1]);
837        }
838        EXPECT_NE(socketFd[1], -1);
839    }
840
841    if (!daemon->InitEnvironment()) {
842        daemon->CleanupSockets();
843    }
844    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest015: end.";
845}
846
847std::vector<FaultLoggerdStatsRequest> InitStatsRequests()
848{
849    std::vector<FaultLoggerdStatsRequest> statsRequest;
850    {
851        FaultLoggerdStatsRequest requst{};
852        requst.type = PROCESS_DUMP;
853        requst.signalTime = GetTimeMilliSeconds();
854        requst.pid = 1;
855        requst.processdumpStartTime = time(nullptr);
856        requst.processdumpFinishTime = time(nullptr) + 10; // 10 : Get the last 10 seconds of the current time
857        statsRequest.emplace_back(requst);
858    }
859    {
860        FaultLoggerdStatsRequest requst{};
861        auto lastRequst = statsRequest.back();
862        requst.type = DUMP_CATCHER;
863        requst.pid = lastRequst.pid;
864        requst.requestTime = time(nullptr);
865        requst.dumpCatcherFinishTime = time(nullptr) + 10; // 10 : Get the last 10 seconds of the current time
866        requst.result = 1;
867        statsRequest.emplace_back(requst);
868    }
869    {
870        FaultLoggerdStatsRequest requst{};
871        requst.type = DUMP_CATCHER;
872        requst.pid = 1;
873        requst.requestTime = time(nullptr);
874        requst.dumpCatcherFinishTime = time(nullptr) + 10; // 10 : Get the last 10 seconds of the current time
875        requst.result = 1;
876        statsRequest.emplace_back(requst);
877    }
878    return statsRequest;
879}
880
881/**
882 * @tc.name: FaultLoggerDaemonTest016
883 * @tc.desc: test FaultLoggerDaemon for HandleDumpStats
884 * @tc.type: FUNC
885 */
886HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest016, TestSize.Level4)
887{
888    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest016: start.";
889    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
890    std::vector<FaultLoggerdStatsRequest> statsRequest = InitStatsRequests();
891    for (auto requst : statsRequest) {
892        HandleRequestTestCommon(daemon, reinterpret_cast<char*>(&requst), sizeof(FaultLoggerdStatsRequest), nullptr);
893    }
894    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest016: end.";
895}
896
897/**
898 * @tc.name: FaultLoggerDaemonTest017
899 * @tc.desc: test FaultLoggerDaemon for HandleRequest
900 * @tc.type: FUNC
901 */
902HWTEST_F (FaultLoggerDaemonTest, FaultLoggerDaemonTest017, TestSize.Level4)
903{
904    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest017: start.";
905    std::shared_ptr<FaultLoggerDaemon> daemon = std::make_shared<FaultLoggerDaemon>();
906    HandleRequestByClientTypeForDefaultClientTest(daemon);
907    HandleRequestByClientTypeTest(daemon);
908    GTEST_LOG_(INFO) << "FaultLoggerDaemonTest017: end.";
909}
910}