1/*
2 * Copyright (c) 2022 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 <cerrno>
17#include <cstdio>
18#include <ctime>
19#include <sys/types.h>
20#include <sys/mount.h>
21#include <sys/stat.h>
22
23#include "init.h"
24#include "device.h"
25#include "init_cmds.h"
26#include "init_log.h"
27#include "init_service.h"
28#include "init_unittest.h"
29#include "init_adapter.h"
30#include "init_utils.h"
31#include "loop_event.h"
32#include "param_stub.h"
33#include "fs_manager/fs_manager.h"
34#include "fd_holder.h"
35#include "fd_holder_service.h"
36#include "bootstage.h"
37#include "parameter.h"
38
39using namespace testing::ext;
40using namespace std;
41
42extern "C" {
43INIT_STATIC void ProcessSignal(const struct signalfd_siginfo *siginfo);
44}
45
46namespace init_ut {
47class InitUnitTest : public testing::Test {
48public:
49    static void SetUpTestCase(void) {};
50    static void TearDownTestCase(void) {};
51    void SetUp() {};
52    void TearDown() {};
53};
54
55HWTEST_F(InitUnitTest, TestSignalHandle, TestSize.Level1)
56{
57    struct signalfd_siginfo siginfo;
58    siginfo.ssi_signo = SIGCHLD;
59    ProcessSignal(&siginfo);
60    siginfo.ssi_signo = SIGTERM;
61    ProcessSignal(&siginfo);
62    siginfo.ssi_signo = SIGUSR1;
63    ProcessSignal(&siginfo);
64    SUCCEED();
65}
66
67HWTEST_F(InitUnitTest, TestSystemPrepare, TestSize.Level1)
68{
69    SetStubResult(STUB_MOUNT, -1);
70    SetStubResult(STUB_MKNODE, -1);
71    CreateFsAndDeviceNode();
72
73    SetStubResult(STUB_MOUNT, 0);
74    SetStubResult(STUB_MKNODE, 0);
75    CreateFsAndDeviceNode();
76}
77
78HWTEST_F(InitUnitTest, TestSystemExecRcs, TestSize.Level1)
79{
80    SystemExecuteRcs();
81    Service *service = GetServiceByName("param_watcher");
82    int ret = KeepCapability(service);
83    EXPECT_EQ(ret, 0);
84    ret = SetAmbientCapability(34); // CAP_SYSLOG
85    EXPECT_EQ(ret, 0);
86}
87
88static void TestProcessTimer(const TimerHandle taskHandle, void *context)
89{
90    static int count = 0;
91    printf("ProcessTimer %d\n", count);
92    if (count == 0) { // 2 stop
93        // set service pid for test
94        Service *service = GetServiceByName("param_watcher");
95        if (service != nullptr) {
96            service->pid = getpid();
97        }
98        int fds1[] = {1, 0};
99        ServiceSaveFd("param_watcher", fds1, ARRAY_LENGTH(fds1));
100        ServiceSaveFdWithPoll("param_watcher", fds1, 0);
101        ServiceSaveFdWithPoll("param_watcher", fds1, ARRAY_LENGTH(fds1));
102        EXPECT_EQ(setenv("OHOS_FD_HOLD_param_watcher", "1 0", 0), 0);
103
104        size_t fdCount = 0;
105        int *fds = ServiceGetFd("param_watcher", &fdCount);
106        EXPECT_TRUE(fds != nullptr);
107        free(fds);
108
109        ServiceSaveFd("testservice", fds1, ARRAY_LENGTH(fds1));
110        ServiceSaveFd("deviceinfoservice", fds1, ARRAY_LENGTH(fds1));
111    }
112    if (count == 1) {
113        LE_StopTimer(LE_GetDefaultLoop(), taskHandle);
114        LE_StopLoop(LE_GetDefaultLoop());
115    }
116    count++;
117}
118
119HWTEST_F(InitUnitTest, TestFdHoldService, TestSize.Level1)
120{
121    RegisterFdHoldWatcher(-1);
122    TimerHandle timer = nullptr;
123    int ret = LE_CreateTimer(LE_GetDefaultLoop(), &timer, TestProcessTimer, nullptr);
124    EXPECT_EQ(ret, 0);
125    ret = LE_StartTimer(LE_GetDefaultLoop(), timer, 500, 4);
126    EXPECT_EQ(ret, 0);
127    SystemRun();
128}
129
130HWTEST_F(InitUnitTest, TestInitLog, TestSize.Level1)
131{
132    // test log
133    CheckAndCreateDir(INIT_LOG_PATH);
134    SetInitLogLevel(INIT_DEBUG);
135    INIT_LOGI("TestInitLog");
136    INIT_LOGV("TestInitLog");
137    INIT_LOGE("TestInitLog");
138    INIT_LOGW("TestInitLog");
139    INIT_LOGF("TestInitLog");
140    // restore log level
141    int32_t loglevel = GetIntParameter("persist.init.debug.loglevel", INIT_ERROR);
142    SetInitLogLevel((InitLogLevel)loglevel);
143}
144}
145