1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2022-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 "dfx_func_hook_unittest.h"
17800b99b8Sopenharmony_ci
18800b99b8Sopenharmony_ci#include <csignal>
19800b99b8Sopenharmony_ci#include <sys/wait.h>
20800b99b8Sopenharmony_ci#include <unistd.h>
21800b99b8Sopenharmony_ci
22800b99b8Sopenharmony_ci#include "dfx_exit_hook.h"
23800b99b8Sopenharmony_ci
24800b99b8Sopenharmony_ciusing namespace OHOS::HiviewDFX;
25800b99b8Sopenharmony_ciusing namespace testing::ext;
26800b99b8Sopenharmony_ciusing namespace std;
27800b99b8Sopenharmony_civoid DfxFuncHookUnitTest::SetUpTestCase(void)
28800b99b8Sopenharmony_ci{
29800b99b8Sopenharmony_ci}
30800b99b8Sopenharmony_ci
31800b99b8Sopenharmony_civoid DfxFuncHookUnitTest::TearDownTestCase(void)
32800b99b8Sopenharmony_ci{
33800b99b8Sopenharmony_ci}
34800b99b8Sopenharmony_ci
35800b99b8Sopenharmony_civoid DfxFuncHookUnitTest::SetUp(void)
36800b99b8Sopenharmony_ci{
37800b99b8Sopenharmony_ci    StartHookExitFunc();
38800b99b8Sopenharmony_ci}
39800b99b8Sopenharmony_ci
40800b99b8Sopenharmony_civoid DfxFuncHookUnitTest::TearDown(void)
41800b99b8Sopenharmony_ci{
42800b99b8Sopenharmony_ci}
43800b99b8Sopenharmony_ci
44800b99b8Sopenharmony_cinamespace {
45800b99b8Sopenharmony_ci/**
46800b99b8Sopenharmony_ci * @tc.name: FuncHookTest001
47800b99b8Sopenharmony_ci * @tc.desc: fork a child process and exit with calling _exit
48800b99b8Sopenharmony_ci * @tc.type: FUNC
49800b99b8Sopenharmony_ci */
50800b99b8Sopenharmony_ciHWTEST_F(DfxFuncHookUnitTest, FuncHookTest001, TestSize.Level3)
51800b99b8Sopenharmony_ci{
52800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FuncHookTest001: start.";
53800b99b8Sopenharmony_ci    const int retCode = 99;
54800b99b8Sopenharmony_ci    pid_t pid = fork();
55800b99b8Sopenharmony_ci    bool isSuccess = pid >= 0;
56800b99b8Sopenharmony_ci    if (!isSuccess) {
57800b99b8Sopenharmony_ci        ASSERT_FALSE(isSuccess);
58800b99b8Sopenharmony_ci        return;
59800b99b8Sopenharmony_ci    }
60800b99b8Sopenharmony_ci    if (pid == 0) {
61800b99b8Sopenharmony_ci        exit(retCode);
62800b99b8Sopenharmony_ci    } else {
63800b99b8Sopenharmony_ci        int status;
64800b99b8Sopenharmony_ci        int ret = waitpid(pid, &status, 0);
65800b99b8Sopenharmony_ci        printf("child ret with pid:%d status:%d\n", ret, status);
66800b99b8Sopenharmony_ci        if (WIFEXITED(status)) {
67800b99b8Sopenharmony_ci            int code = WEXITSTATUS(status);
68800b99b8Sopenharmony_ci            printf("Exit code was %d\n", code);
69800b99b8Sopenharmony_ci            EXPECT_EQ(code, retCode);
70800b99b8Sopenharmony_ci        }
71800b99b8Sopenharmony_ci    }
72800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FuncHookTest001: end.";
73800b99b8Sopenharmony_ci}
74800b99b8Sopenharmony_ci
75800b99b8Sopenharmony_ci/**
76800b99b8Sopenharmony_ci * @tc.name: FuncHookTest002
77800b99b8Sopenharmony_ci * @tc.desc: fork a child process and kill it in parent process
78800b99b8Sopenharmony_ci * @tc.type: FUNC
79800b99b8Sopenharmony_ci */
80800b99b8Sopenharmony_ciHWTEST_F(DfxFuncHookUnitTest, FuncHookTest002, TestSize.Level3)
81800b99b8Sopenharmony_ci{
82800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FuncHookTest002: start.";
83800b99b8Sopenharmony_ci    pid_t pid = fork();
84800b99b8Sopenharmony_ci    bool isSuccess = pid >= 0;
85800b99b8Sopenharmony_ci    if (!isSuccess) {
86800b99b8Sopenharmony_ci        ASSERT_FALSE(isSuccess);
87800b99b8Sopenharmony_ci        return;
88800b99b8Sopenharmony_ci    }
89800b99b8Sopenharmony_ci    if (pid == 0) {
90800b99b8Sopenharmony_ci        while (true) {
91800b99b8Sopenharmony_ci            sleep(1);
92800b99b8Sopenharmony_ci        }
93800b99b8Sopenharmony_ci    } else {
94800b99b8Sopenharmony_ci        printf("child pid:%d\n", pid);
95800b99b8Sopenharmony_ci        kill(pid, SIGKILL);
96800b99b8Sopenharmony_ci        int status;
97800b99b8Sopenharmony_ci        int ret = waitpid(pid, &status, 0);
98800b99b8Sopenharmony_ci        printf("child ret with pid:%d status:%d\n", ret, status);
99800b99b8Sopenharmony_ci        if (WIFSIGNALED(status)) {
100800b99b8Sopenharmony_ci            int signal = WTERMSIG(status);
101800b99b8Sopenharmony_ci            printf("Exit signal was %d\n", signal);
102800b99b8Sopenharmony_ci            EXPECT_EQ(signal, SIGKILL);
103800b99b8Sopenharmony_ci        }
104800b99b8Sopenharmony_ci    }
105800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "FuncHookTest002: end.";
106800b99b8Sopenharmony_ci}
107800b99b8Sopenharmony_ci}
108