1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License.
5800b99b8Sopenharmony_ci * You may obtain a copy of the License at
6800b99b8Sopenharmony_ci *
7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8800b99b8Sopenharmony_ci *
9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and
13800b99b8Sopenharmony_ci * limitations under the License.
14800b99b8Sopenharmony_ci */
15800b99b8Sopenharmony_ci
16800b99b8Sopenharmony_ci#include <fcntl.h>
17800b99b8Sopenharmony_ci#include <gtest/gtest.h>
18800b99b8Sopenharmony_ci#include <sys/socket.h>
19800b99b8Sopenharmony_ci#include <sys/un.h>
20800b99b8Sopenharmony_ci#include <unistd.h>
21800b99b8Sopenharmony_ci
22800b99b8Sopenharmony_ci#include "dfx_define.h"
23800b99b8Sopenharmony_ci#include "dfx_test_util.h"
24800b99b8Sopenharmony_ci#include "faultloggerd_client.h"
25800b99b8Sopenharmony_ci#include "faultloggerd_socket.h"
26800b99b8Sopenharmony_ci
27800b99b8Sopenharmony_ci#if defined(HAS_LIB_SELINUX)
28800b99b8Sopenharmony_ci#include <selinux/selinux.h>
29800b99b8Sopenharmony_ci#endif
30800b99b8Sopenharmony_ci
31800b99b8Sopenharmony_ciusing namespace testing;
32800b99b8Sopenharmony_ciusing namespace testing::ext;
33800b99b8Sopenharmony_ci
34800b99b8Sopenharmony_cinamespace OHOS {
35800b99b8Sopenharmony_cinamespace HiviewDFX {
36800b99b8Sopenharmony_ciclass FaultloggerdClientTest : public testing::Test {
37800b99b8Sopenharmony_cipublic:
38800b99b8Sopenharmony_ci    static void SetUpTestCase();
39800b99b8Sopenharmony_ci    static void TearDownTestCase();
40800b99b8Sopenharmony_ci    void SetUp();
41800b99b8Sopenharmony_ci    void TearDown();
42800b99b8Sopenharmony_ci};
43800b99b8Sopenharmony_ci
44800b99b8Sopenharmony_civoid FaultloggerdClientTest::SetUpTestCase()
45800b99b8Sopenharmony_ci{
46800b99b8Sopenharmony_ci}
47800b99b8Sopenharmony_ci
48800b99b8Sopenharmony_civoid FaultloggerdClientTest::TearDownTestCase()
49800b99b8Sopenharmony_ci{
50800b99b8Sopenharmony_ci}
51800b99b8Sopenharmony_ci
52800b99b8Sopenharmony_civoid FaultloggerdClientTest::SetUp()
53800b99b8Sopenharmony_ci{
54800b99b8Sopenharmony_ci}
55800b99b8Sopenharmony_ci
56800b99b8Sopenharmony_civoid FaultloggerdClientTest::TearDown()
57800b99b8Sopenharmony_ci{
58800b99b8Sopenharmony_ci}
59800b99b8Sopenharmony_ci
60800b99b8Sopenharmony_cibool IsSelinuxEnforced()
61800b99b8Sopenharmony_ci{
62800b99b8Sopenharmony_ci    std::string cmd = "getenforce";
63800b99b8Sopenharmony_ci    std::string selinuxStatus = ExecuteCommands(cmd);
64800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "getenforce return:" << selinuxStatus;
65800b99b8Sopenharmony_ci    return (selinuxStatus.find("Enforcing") != std::string::npos) ? true : false;
66800b99b8Sopenharmony_ci}
67800b99b8Sopenharmony_ci
68800b99b8Sopenharmony_ci/**
69800b99b8Sopenharmony_ci * @tc.name: FaultloggerdClientTest001
70800b99b8Sopenharmony_ci * @tc.desc: request a file descriptor for logging crash
71800b99b8Sopenharmony_ci * @tc.type: FUNC
72800b99b8Sopenharmony_ci */
73800b99b8Sopenharmony_ciHWTEST_F(FaultloggerdClientTest, FaultloggerdClientTest001, TestSize.Level2)
74800b99b8Sopenharmony_ci{
75800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest001: start.";
76800b99b8Sopenharmony_ci    int32_t fd = RequestFileDescriptor(FaultLoggerType::CPP_CRASH);
77800b99b8Sopenharmony_ci    ASSERT_GT(fd, 0);
78800b99b8Sopenharmony_ci    close(fd);
79800b99b8Sopenharmony_ci
80800b99b8Sopenharmony_ci    fd = RequestFileDescriptor(FaultLoggerType::JS_HEAP_SNAPSHOT);
81800b99b8Sopenharmony_ci    ASSERT_GT(fd, 0);
82800b99b8Sopenharmony_ci    close(fd);
83800b99b8Sopenharmony_ci
84800b99b8Sopenharmony_ci    fd = RequestFileDescriptor(FaultLoggerType::JS_RAW_SNAPSHOT);
85800b99b8Sopenharmony_ci    ASSERT_GT(fd, 0);
86800b99b8Sopenharmony_ci    close(fd);
87800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest001: end.";
88800b99b8Sopenharmony_ci}
89800b99b8Sopenharmony_ci
90800b99b8Sopenharmony_ci/**
91800b99b8Sopenharmony_ci * @tc.name: FaultloggerdClientTest002
92800b99b8Sopenharmony_ci * @tc.desc: request a file descriptor for logging with app uid
93800b99b8Sopenharmony_ci * @tc.type: FUNC
94800b99b8Sopenharmony_ci */
95800b99b8Sopenharmony_ciHWTEST_F(FaultloggerdClientTest, FaultloggerdClientTest002, TestSize.Level2)
96800b99b8Sopenharmony_ci{
97800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest002: start.";
98800b99b8Sopenharmony_ci    int32_t pid = fork();
99800b99b8Sopenharmony_ci    if (pid == 0) {
100800b99b8Sopenharmony_ci        int ret = 0;
101800b99b8Sopenharmony_ci        constexpr int32_t appUid = 100068;
102800b99b8Sopenharmony_ci        setuid(appUid);
103800b99b8Sopenharmony_ci        do {
104800b99b8Sopenharmony_ci            int32_t fd = RequestFileDescriptor(FaultLoggerType::CPP_CRASH);
105800b99b8Sopenharmony_ci            if (fd < 0) {
106800b99b8Sopenharmony_ci                ret = -1;
107800b99b8Sopenharmony_ci                break;
108800b99b8Sopenharmony_ci            }
109800b99b8Sopenharmony_ci            close(fd);
110800b99b8Sopenharmony_ci
111800b99b8Sopenharmony_ci            fd = RequestFileDescriptor(FaultLoggerType::JS_HEAP_SNAPSHOT);
112800b99b8Sopenharmony_ci            if (fd < 0) {
113800b99b8Sopenharmony_ci                ret = -1;
114800b99b8Sopenharmony_ci                break;
115800b99b8Sopenharmony_ci            }
116800b99b8Sopenharmony_ci            close(fd);
117800b99b8Sopenharmony_ci
118800b99b8Sopenharmony_ci            fd = RequestFileDescriptor(FaultLoggerType::JS_RAW_SNAPSHOT);
119800b99b8Sopenharmony_ci            if (fd < 0) {
120800b99b8Sopenharmony_ci                ret = -1;
121800b99b8Sopenharmony_ci                break;
122800b99b8Sopenharmony_ci            }
123800b99b8Sopenharmony_ci            close(fd);
124800b99b8Sopenharmony_ci        } while (false);
125800b99b8Sopenharmony_ci        exit(ret);
126800b99b8Sopenharmony_ci    } else if (pid > 0) {
127800b99b8Sopenharmony_ci        int status;
128800b99b8Sopenharmony_ci        bool isSuccess = waitpid(pid, &status, 0) != -1;
129800b99b8Sopenharmony_ci        if (!isSuccess) {
130800b99b8Sopenharmony_ci            ASSERT_FALSE(isSuccess);
131800b99b8Sopenharmony_ci            return;
132800b99b8Sopenharmony_ci        }
133800b99b8Sopenharmony_ci
134800b99b8Sopenharmony_ci        int exitCode = -1;
135800b99b8Sopenharmony_ci        if (WIFEXITED(status)) {
136800b99b8Sopenharmony_ci            exitCode = WEXITSTATUS(status);
137800b99b8Sopenharmony_ci            printf("Exit status was %d\n", exitCode);
138800b99b8Sopenharmony_ci        }
139800b99b8Sopenharmony_ci        ASSERT_EQ(exitCode, 0);
140800b99b8Sopenharmony_ci    }
141800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest002: end.";
142800b99b8Sopenharmony_ci}
143800b99b8Sopenharmony_ci
144800b99b8Sopenharmony_ci/**
145800b99b8Sopenharmony_ci * @tc.name: FaultloggerdClientTest003
146800b99b8Sopenharmony_ci * @tc.desc: request a file descriptor for logging with inconsistent pid
147800b99b8Sopenharmony_ci * @tc.type: FUNC
148800b99b8Sopenharmony_ci */
149800b99b8Sopenharmony_ciHWTEST_F(FaultloggerdClientTest, FaultloggerdClientTest003, TestSize.Level2)
150800b99b8Sopenharmony_ci{
151800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest003: start.";
152800b99b8Sopenharmony_ci    int32_t pid = fork();
153800b99b8Sopenharmony_ci    if (pid == 0) {
154800b99b8Sopenharmony_ci        int ret = 1;
155800b99b8Sopenharmony_ci        constexpr int32_t appUid = 100068;
156800b99b8Sopenharmony_ci        setuid(appUid);
157800b99b8Sopenharmony_ci        FaultLoggerdRequest request;
158800b99b8Sopenharmony_ci        request.type = FaultLoggerType::JS_HEAP_SNAPSHOT;
159800b99b8Sopenharmony_ci        request.pid = appUid;
160800b99b8Sopenharmony_ci        int32_t fd = RequestFileDescriptorEx(&request);
161800b99b8Sopenharmony_ci        if (fd >= 0) {
162800b99b8Sopenharmony_ci            close(fd);
163800b99b8Sopenharmony_ci            ret = 0;
164800b99b8Sopenharmony_ci        }
165800b99b8Sopenharmony_ci        exit(ret);
166800b99b8Sopenharmony_ci    } else if (pid > 0) {
167800b99b8Sopenharmony_ci        int status;
168800b99b8Sopenharmony_ci        bool isSuccess = waitpid(pid, &status, 0) != -1;
169800b99b8Sopenharmony_ci        if (!isSuccess) {
170800b99b8Sopenharmony_ci            ASSERT_FALSE(isSuccess);
171800b99b8Sopenharmony_ci            return;
172800b99b8Sopenharmony_ci        }
173800b99b8Sopenharmony_ci
174800b99b8Sopenharmony_ci        int exitCode = -1;
175800b99b8Sopenharmony_ci        if (WIFEXITED(status)) {
176800b99b8Sopenharmony_ci            exitCode = WEXITSTATUS(status);
177800b99b8Sopenharmony_ci            printf("Exit status was %d\n", exitCode);
178800b99b8Sopenharmony_ci        }
179800b99b8Sopenharmony_ci        ASSERT_EQ(exitCode, 1);
180800b99b8Sopenharmony_ci    }
181800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest003: end.";
182800b99b8Sopenharmony_ci}
183800b99b8Sopenharmony_ci#if defined(HAS_LIB_SELINUX)
184800b99b8Sopenharmony_ci/**
185800b99b8Sopenharmony_ci * @tc.name: FaultloggerdClientTest004
186800b99b8Sopenharmony_ci * @tc.desc: request a file descriptor for logging with inconsistent pid but in processdump scontext
187800b99b8Sopenharmony_ci * @tc.type: FUNC
188800b99b8Sopenharmony_ci */
189800b99b8Sopenharmony_ciHWTEST_F(FaultloggerdClientTest, FaultloggerdClientTest004, TestSize.Level2)
190800b99b8Sopenharmony_ci{
191800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest004: start.";
192800b99b8Sopenharmony_ci
193800b99b8Sopenharmony_ci    // If selinux is not opened, skip this test item
194800b99b8Sopenharmony_ci    bool isSuccess = IsSelinuxEnforced();
195800b99b8Sopenharmony_ci    if (!isSuccess) {
196800b99b8Sopenharmony_ci        ASSERT_FALSE(isSuccess);
197800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "Selinux is not opened, skip FaultloggerdClientTest004";
198800b99b8Sopenharmony_ci        return;
199800b99b8Sopenharmony_ci    }
200800b99b8Sopenharmony_ci    int32_t pid = fork();
201800b99b8Sopenharmony_ci    if (pid == 0) {
202800b99b8Sopenharmony_ci        int ret = 1;
203800b99b8Sopenharmony_ci        constexpr int32_t appUid = 100068;
204800b99b8Sopenharmony_ci        setcon("u:r:processdump:s0");
205800b99b8Sopenharmony_ci        setuid(appUid);
206800b99b8Sopenharmony_ci        FaultLoggerdRequest request;
207800b99b8Sopenharmony_ci        request.type = FaultLoggerType::JS_HEAP_SNAPSHOT;
208800b99b8Sopenharmony_ci        request.pid = appUid;
209800b99b8Sopenharmony_ci        int32_t fd = RequestFileDescriptorEx(&request);
210800b99b8Sopenharmony_ci        if (fd >= 0) {
211800b99b8Sopenharmony_ci            close(fd);
212800b99b8Sopenharmony_ci            ret = 0;
213800b99b8Sopenharmony_ci        }
214800b99b8Sopenharmony_ci        exit(ret);
215800b99b8Sopenharmony_ci    } else if (pid > 0) {
216800b99b8Sopenharmony_ci        int status;
217800b99b8Sopenharmony_ci        bool isSuccess = waitpid(pid, &status, 0) != -1;
218800b99b8Sopenharmony_ci        if (!isSuccess) {
219800b99b8Sopenharmony_ci            ASSERT_FALSE(isSuccess);
220800b99b8Sopenharmony_ci            return;
221800b99b8Sopenharmony_ci        }
222800b99b8Sopenharmony_ci
223800b99b8Sopenharmony_ci        int exitCode = -1;
224800b99b8Sopenharmony_ci        if (WIFEXITED(status)) {
225800b99b8Sopenharmony_ci            exitCode = WEXITSTATUS(status);
226800b99b8Sopenharmony_ci            printf("Exit status was %d\n", exitCode);
227800b99b8Sopenharmony_ci        }
228800b99b8Sopenharmony_ci        ASSERT_EQ(exitCode, 0);
229800b99b8Sopenharmony_ci    }
230800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest004: end.";
231800b99b8Sopenharmony_ci}
232800b99b8Sopenharmony_ci
233800b99b8Sopenharmony_ci/**
234800b99b8Sopenharmony_ci * @tc.name: FaultloggerdClientTest005
235800b99b8Sopenharmony_ci * @tc.desc: sdkdump request which selinux label belongs to { hiview hidumper foundation }
236800b99b8Sopenharmony_ci * @tc.type: FUNC
237800b99b8Sopenharmony_ci */
238800b99b8Sopenharmony_ciHWTEST_F(FaultloggerdClientTest, FaultloggerdClientTest005, TestSize.Level2)
239800b99b8Sopenharmony_ci{
240800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest005: start.";
241800b99b8Sopenharmony_ci
242800b99b8Sopenharmony_ci    // If selinux is not opened, skip this test item
243800b99b8Sopenharmony_ci    bool isSuccess = IsSelinuxEnforced();
244800b99b8Sopenharmony_ci    if (!isSuccess) {
245800b99b8Sopenharmony_ci        ASSERT_FALSE(isSuccess);
246800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "Selinux is not opened, skip FaultloggerdClientTest005";
247800b99b8Sopenharmony_ci        return;
248800b99b8Sopenharmony_ci    }
249800b99b8Sopenharmony_ci
250800b99b8Sopenharmony_ci    int32_t pid = fork();
251800b99b8Sopenharmony_ci    if (pid == 0) {
252800b99b8Sopenharmony_ci        int ret = 1;
253800b99b8Sopenharmony_ci        constexpr int32_t appUid = 100068;
254800b99b8Sopenharmony_ci        setcon("u:r:hiview:s0");
255800b99b8Sopenharmony_ci        setuid(appUid);
256800b99b8Sopenharmony_ci        int resp = RequestSdkDump(1, 1);
257800b99b8Sopenharmony_ci        if (resp == FaultLoggerCheckPermissionResp::CHECK_PERMISSION_PASS) {
258800b99b8Sopenharmony_ci            ret = 0;
259800b99b8Sopenharmony_ci        }
260800b99b8Sopenharmony_ci        exit(ret);
261800b99b8Sopenharmony_ci    } else if (pid > 0) {
262800b99b8Sopenharmony_ci        int status;
263800b99b8Sopenharmony_ci        bool isSuccess = waitpid(pid, &status, 0) != -1;
264800b99b8Sopenharmony_ci        if (!isSuccess) {
265800b99b8Sopenharmony_ci            ASSERT_FALSE(isSuccess);
266800b99b8Sopenharmony_ci            return;
267800b99b8Sopenharmony_ci        }
268800b99b8Sopenharmony_ci
269800b99b8Sopenharmony_ci        int exitCode = -1;
270800b99b8Sopenharmony_ci        if (WIFEXITED(status)) {
271800b99b8Sopenharmony_ci            exitCode = WEXITSTATUS(status);
272800b99b8Sopenharmony_ci            printf("Exit status was %d\n", exitCode);
273800b99b8Sopenharmony_ci        }
274800b99b8Sopenharmony_ci        ASSERT_EQ(exitCode, 0);
275800b99b8Sopenharmony_ci    }
276800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest005: end.";
277800b99b8Sopenharmony_ci}
278800b99b8Sopenharmony_ci
279800b99b8Sopenharmony_ci/**
280800b99b8Sopenharmony_ci * @tc.name: FaultloggerdClientTest006
281800b99b8Sopenharmony_ci * @tc.desc: sdkdump request which selinux label doesn't belongs to { hiview hidumper foundation }
282800b99b8Sopenharmony_ci * @tc.type: FUNC
283800b99b8Sopenharmony_ci */
284800b99b8Sopenharmony_ciHWTEST_F(FaultloggerdClientTest, FaultloggerdClientTest006, TestSize.Level2)
285800b99b8Sopenharmony_ci{
286800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest006: start.";
287800b99b8Sopenharmony_ci
288800b99b8Sopenharmony_ci    // If selinux is not opened, skip this test item
289800b99b8Sopenharmony_ci    bool isSuccess = IsSelinuxEnforced();
290800b99b8Sopenharmony_ci    if (!isSuccess) {
291800b99b8Sopenharmony_ci        ASSERT_FALSE(isSuccess);
292800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "Selinux is not opened, skip FaultloggerdClientTest006";
293800b99b8Sopenharmony_ci        return;
294800b99b8Sopenharmony_ci    }
295800b99b8Sopenharmony_ci    int32_t pid = fork();
296800b99b8Sopenharmony_ci    if (pid == 0) {
297800b99b8Sopenharmony_ci        int ret = 1;
298800b99b8Sopenharmony_ci        constexpr int32_t appUid = 100068;
299800b99b8Sopenharmony_ci        setcon("u:r:wifi_host:s0");
300800b99b8Sopenharmony_ci        setuid(appUid);
301800b99b8Sopenharmony_ci        int resp = RequestSdkDump(1, 1);
302800b99b8Sopenharmony_ci        if (resp == FaultLoggerCheckPermissionResp::CHECK_PERMISSION_REJECT) {
303800b99b8Sopenharmony_ci            ret = 0;
304800b99b8Sopenharmony_ci        }
305800b99b8Sopenharmony_ci        exit(ret);
306800b99b8Sopenharmony_ci    } else if (pid > 0) {
307800b99b8Sopenharmony_ci        int status;
308800b99b8Sopenharmony_ci        bool isSuccess = waitpid(pid, &status, 0) != -1;
309800b99b8Sopenharmony_ci        if (!isSuccess) {
310800b99b8Sopenharmony_ci            ASSERT_FALSE(isSuccess);
311800b99b8Sopenharmony_ci            return;
312800b99b8Sopenharmony_ci        }
313800b99b8Sopenharmony_ci
314800b99b8Sopenharmony_ci        int exitCode = -1;
315800b99b8Sopenharmony_ci        if (WIFEXITED(status)) {
316800b99b8Sopenharmony_ci            exitCode = WEXITSTATUS(status);
317800b99b8Sopenharmony_ci            printf("Exit status was %d\n", exitCode);
318800b99b8Sopenharmony_ci        }
319800b99b8Sopenharmony_ci        ASSERT_EQ(exitCode, 0);
320800b99b8Sopenharmony_ci    }
321800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest006: end.";
322800b99b8Sopenharmony_ci}
323800b99b8Sopenharmony_ci#endif
324800b99b8Sopenharmony_ci
325800b99b8Sopenharmony_ci/**
326800b99b8Sopenharmony_ci * @tc.name: FaultloggerdClientTest007
327800b99b8Sopenharmony_ci * @tc.desc: test FaultloggerdClient exception
328800b99b8Sopenharmony_ci * @tc.type: FUNC
329800b99b8Sopenharmony_ci */
330800b99b8Sopenharmony_ciHWTEST_F(FaultloggerdClientTest, FaultloggerdClientTest007, TestSize.Level2)
331800b99b8Sopenharmony_ci{
332800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest007: start.";
333800b99b8Sopenharmony_ci    int32_t fd = RequestLogFileDescriptor(nullptr);
334800b99b8Sopenharmony_ci    ASSERT_EQ(fd, -1);
335800b99b8Sopenharmony_ci    fd = RequestFileDescriptorEx(nullptr);
336800b99b8Sopenharmony_ci    ASSERT_EQ(fd, -1);
337800b99b8Sopenharmony_ci
338800b99b8Sopenharmony_ci    bool ret = RequestCheckPermission(-1);
339800b99b8Sopenharmony_ci    ASSERT_FALSE(ret);
340800b99b8Sopenharmony_ci
341800b99b8Sopenharmony_ci    int result = RequestPrintTHilog(nullptr, LINE_BUF_SIZE + 1);
342800b99b8Sopenharmony_ci    ASSERT_EQ(result, -1);
343800b99b8Sopenharmony_ci
344800b99b8Sopenharmony_ci    int timeout = 10000; // 10000 : dump timeout ms
345800b99b8Sopenharmony_ci    result = RequestSdkDumpJson(-1, -1, false, timeout);
346800b99b8Sopenharmony_ci    ASSERT_EQ(result, -1);
347800b99b8Sopenharmony_ci    RequestSdkDumpJson(-1, 1, false, timeout);
348800b99b8Sopenharmony_ci    ASSERT_EQ(result, -1);
349800b99b8Sopenharmony_ci    RequestSdkDumpJson(1, -1, false, timeout);
350800b99b8Sopenharmony_ci    ASSERT_EQ(result, -1);
351800b99b8Sopenharmony_ci    RequestSdkDumpJson(1, 1, false, timeout);
352800b99b8Sopenharmony_ci    ASSERT_EQ(result, -1);
353800b99b8Sopenharmony_ci
354800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdClientTest007: end.";
355800b99b8Sopenharmony_ci}
356800b99b8Sopenharmony_ci
357800b99b8Sopenharmony_civoid DoClientProcess(const std::string& socketFileName)
358800b99b8Sopenharmony_ci{
359800b99b8Sopenharmony_ci    // wait 2 seconds, waiting for the service to be ready
360800b99b8Sopenharmony_ci    sleep(2);
361800b99b8Sopenharmony_ci    int clientSocketFd = -1;
362800b99b8Sopenharmony_ci
363800b99b8Sopenharmony_ci    // socket connect time out 10 second
364800b99b8Sopenharmony_ci    bool retBool = StartConnect(clientSocketFd, socketFileName.c_str(), 10);
365800b99b8Sopenharmony_ci    ASSERT_TRUE(retBool);
366800b99b8Sopenharmony_ci    ASSERT_NE(clientSocketFd, -1);
367800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "child connect finished, client fd:" << clientSocketFd;
368800b99b8Sopenharmony_ci
369800b99b8Sopenharmony_ci    int data = 12345; // 12345 is for server Cred test
370800b99b8Sopenharmony_ci    retBool = SendMsgIovToSocket(clientSocketFd, reinterpret_cast<void *>(&data), sizeof(data));
371800b99b8Sopenharmony_ci    ASSERT_TRUE(retBool);
372800b99b8Sopenharmony_ci
373800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "Start read file desc";
374800b99b8Sopenharmony_ci    int testFd = ReadFileDescriptorFromSocket(clientSocketFd);
375800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "recv testFd:" << testFd;
376800b99b8Sopenharmony_ci    ASSERT_NE(testFd, -1);
377800b99b8Sopenharmony_ci    close(clientSocketFd);
378800b99b8Sopenharmony_ci    close(testFd);
379800b99b8Sopenharmony_ci}
380800b99b8Sopenharmony_ci
381800b99b8Sopenharmony_civoid DoServerProcess(const std::string& socketFileName)
382800b99b8Sopenharmony_ci{
383800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "server prepare listen";
384800b99b8Sopenharmony_ci    int32_t serverSocketFd = -1;
385800b99b8Sopenharmony_ci    std::string testFileName = "/data/test.txt";
386800b99b8Sopenharmony_ci
387800b99b8Sopenharmony_ci    // 5: means max connection count is 5
388800b99b8Sopenharmony_ci    bool ret = StartListen(serverSocketFd, socketFileName.c_str(), 5);
389800b99b8Sopenharmony_ci    ASSERT_TRUE(ret);
390800b99b8Sopenharmony_ci    ASSERT_NE(serverSocketFd, -1);
391800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "server start listen fd:" << serverSocketFd;
392800b99b8Sopenharmony_ci
393800b99b8Sopenharmony_ci    struct timeval timev = {
394800b99b8Sopenharmony_ci        20, // recv timeout 20 seconds
395800b99b8Sopenharmony_ci        0
396800b99b8Sopenharmony_ci    };
397800b99b8Sopenharmony_ci    void* pTimev = &timev;
398800b99b8Sopenharmony_ci    int retOpt = OHOS_TEMP_FAILURE_RETRY(setsockopt(serverSocketFd, SOL_SOCKET, SO_RCVTIMEO,
399800b99b8Sopenharmony_ci        static_cast<const char*>(pTimev), sizeof(struct timeval)));
400800b99b8Sopenharmony_ci    ASSERT_NE(retOpt, -1);
401800b99b8Sopenharmony_ci
402800b99b8Sopenharmony_ci    struct sockaddr_un clientAddr;
403800b99b8Sopenharmony_ci    socklen_t clientAddrSize = static_cast<socklen_t>(sizeof(clientAddr));
404800b99b8Sopenharmony_ci    int32_t connectionFd = OHOS_TEMP_FAILURE_RETRY(accept(serverSocketFd,
405800b99b8Sopenharmony_ci        reinterpret_cast<struct sockaddr *>(&clientAddr), &clientAddrSize));
406800b99b8Sopenharmony_ci    ASSERT_GT(connectionFd, 0);
407800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "server accept fd:" << connectionFd;
408800b99b8Sopenharmony_ci
409800b99b8Sopenharmony_ci    int optval = 1;
410800b99b8Sopenharmony_ci    retOpt = setsockopt(connectionFd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval));
411800b99b8Sopenharmony_ci    ASSERT_NE(retOpt, -1);
412800b99b8Sopenharmony_ci
413800b99b8Sopenharmony_ci    struct ucred rcred;
414800b99b8Sopenharmony_ci    bool retCred = RecvMsgCredFromSocket(connectionFd, &rcred);
415800b99b8Sopenharmony_ci    ASSERT_TRUE(retCred);
416800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "uid:" << rcred.uid;
417800b99b8Sopenharmony_ci
418800b99b8Sopenharmony_ci    // 0666 for file read and write
419800b99b8Sopenharmony_ci    int testFdServer = open(testFileName.c_str(), O_RDWR | O_CREAT, 0666);
420800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "Start SendFileDescriptorToSocket";
421800b99b8Sopenharmony_ci    SendFileDescriptorToSocket(connectionFd, testFdServer);
422800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "Close server connect fd";
423800b99b8Sopenharmony_ci    close(connectionFd);
424800b99b8Sopenharmony_ci    close(testFdServer);
425800b99b8Sopenharmony_ci    close(serverSocketFd);
426800b99b8Sopenharmony_ci    unlink(testFileName.c_str());
427800b99b8Sopenharmony_ci}
428800b99b8Sopenharmony_ci
429800b99b8Sopenharmony_ci/**
430800b99b8Sopenharmony_ci * @tc.name: FaultloggerdSocketTest001
431800b99b8Sopenharmony_ci * @tc.desc: test StartListen, RecvMsgCredFromSocket and SendMsgCtlToSocket
432800b99b8Sopenharmony_ci * @tc.type: FUNC
433800b99b8Sopenharmony_ci */
434800b99b8Sopenharmony_ciHWTEST_F(FaultloggerdClientTest, FaultloggerdSocketTest001, TestSize.Level2)
435800b99b8Sopenharmony_ci{
436800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdSocketTest001: start.";
437800b99b8Sopenharmony_ci    std::string testSocketName = "faultloggerd.server.test";
438800b99b8Sopenharmony_ci
439800b99b8Sopenharmony_ci    int32_t pid = fork();
440800b99b8Sopenharmony_ci    if (pid == 0) {
441800b99b8Sopenharmony_ci        DoClientProcess(testSocketName);
442800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "client exit";
443800b99b8Sopenharmony_ci        exit(0);
444800b99b8Sopenharmony_ci    } else if (pid > 0) {
445800b99b8Sopenharmony_ci        DoServerProcess(testSocketName);
446800b99b8Sopenharmony_ci
447800b99b8Sopenharmony_ci        int status;
448800b99b8Sopenharmony_ci        bool isSuccess = waitpid(pid, &status, 0) != -1;
449800b99b8Sopenharmony_ci        if (!isSuccess) {
450800b99b8Sopenharmony_ci            ASSERT_FALSE(isSuccess);
451800b99b8Sopenharmony_ci            return;
452800b99b8Sopenharmony_ci        }
453800b99b8Sopenharmony_ci
454800b99b8Sopenharmony_ci        int exitCode = -1;
455800b99b8Sopenharmony_ci        if (WIFEXITED(status)) {
456800b99b8Sopenharmony_ci            exitCode = WEXITSTATUS(status);
457800b99b8Sopenharmony_ci            GTEST_LOG_(INFO) << "Exit status was " << exitCode;
458800b99b8Sopenharmony_ci        }
459800b99b8Sopenharmony_ci        ASSERT_EQ(exitCode, 0);
460800b99b8Sopenharmony_ci    }
461800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FaultloggerdSocketTest001: end.";
462800b99b8Sopenharmony_ci}
463800b99b8Sopenharmony_ci} // namespace HiviewDFX
464800b99b8Sopenharmony_ci} // namepsace OHOS
465