1/*
2 * Copyright (c) 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#include "init_context.h"
16
17#include "param_stub.h"
18#include "securec.h"
19
20using namespace std;
21using namespace testing::ext;
22
23extern "C" {
24struct ForkArgs {
25    int (*childFunc)(const SubInitForkArg *arg);
26    SubInitForkArg args;
27};
28static pid_t g_pid = 1000;
29static pthread_t g_thread = 0;
30
31static void *ThreadFunc(void *arg)
32{
33    printf("Create thread %d \n", gettid());
34    struct ForkArgs *forkArg = static_cast<struct ForkArgs *>(arg);
35    forkArg->childFunc(&forkArg->args);
36    printf("Exit thread %d %d \n", forkArg->args.type, gettid());
37    free(forkArg);
38    g_thread = 0;
39    return nullptr;
40}
41
42pid_t SubInitFork(int (*childFunc)(const SubInitForkArg *arg), const SubInitForkArg *args)
43{
44    if (g_pid >= 0) {
45        struct ForkArgs *forkArg = static_cast<struct ForkArgs *>(malloc(sizeof(struct ForkArgs)));
46        if (forkArg == nullptr) {
47            return -1;
48        }
49        forkArg->childFunc = childFunc;
50        forkArg->args.socket[0] = args->socket[0];
51        forkArg->args.socket[1] = args->socket[1];
52        forkArg->args.type = args->type;
53        int ret = pthread_create(&g_thread, nullptr, ThreadFunc, forkArg);
54        if (ret != 0) {
55            printf("Failed to create thread %d \n", errno);
56            free(forkArg);
57            return -1;
58        }
59        usleep(100); // 100 wait
60    }
61    g_pid++;
62    return g_pid;
63}
64}
65
66namespace init_ut {
67class InitContextUnitTest : public testing::Test {
68public:
69    static void SetUpTestCase(void) {};
70    static void TearDownTestCase(void) {};
71    void SetUp() {};
72    void TearDown() {};
73};
74
75HWTEST_F(InitContextUnitTest, InitSubContextTest_01, TestSize.Level1)
76{
77    g_pid = -3; // -3  test data
78    int ret = StartSubInit(INIT_CONTEXT_CHIPSET);
79    EXPECT_NE(ret, 0);
80    ret = StartSubInit(INIT_CONTEXT_MAIN);
81    EXPECT_NE(ret, 0);
82    g_pid = 100; // 100 test data
83}
84
85HWTEST_F(InitContextUnitTest, InitSubContextTest_02, TestSize.Level1)
86{
87    ConfigContext context = { INIT_CONTEXT_CHIPSET };
88    int ret = ExecuteCmdInSubInit(&context, "mkdir", STARTUP_INIT_UT_PATH"/testsubcontext");
89    EXPECT_EQ(ret, 0);
90    ret = ExecuteCmdInSubInit(&context, "mkdir", STARTUP_INIT_UT_PATH"/testsubcontext1");
91    EXPECT_EQ(ret, 0);
92    ret = ExecuteCmdInSubInit(&context, "mkdir", STARTUP_INIT_UT_PATH"/testsubcontext2");
93    EXPECT_EQ(ret, 0);
94    ret = ExecuteCmdInSubInit(&context, "mkdir", nullptr);
95    EXPECT_EQ(ret, 0);
96    context.type = INIT_CONTEXT_MAIN;
97    ret = ExecuteCmdInSubInit(&context, "mkdir", STARTUP_INIT_UT_PATH"/testsubcontext");
98    EXPECT_NE(ret, 0);
99
100    // fail
101    ret = ExecuteCmdInSubInit(nullptr, "mkdir", STARTUP_INIT_UT_PATH"/testsubcontext");
102    EXPECT_EQ(ret, -1);
103    ret = ExecuteCmdInSubInit(&context, nullptr, STARTUP_INIT_UT_PATH"/testsubcontext");
104    EXPECT_EQ(ret, -1);
105}
106
107HWTEST_F(InitContextUnitTest, InitSubContextTest_03, TestSize.Level1)
108{
109    int ret = StartSubInit(INIT_CONTEXT_CHIPSET);
110    EXPECT_EQ(ret, 0);
111    if (g_thread != 0) {
112        pthread_join(g_thread, nullptr);
113        g_thread = 0;
114    }
115    SubInitInfo *subInfo = GetSubInitInfo(INIT_CONTEXT_CHIPSET);
116    if (subInfo == nullptr) {
117        EXPECT_EQ(1, 0);
118    } else {
119        EXPECT_EQ(2, subInfo->state);
120        StopSubInit(subInfo->subPid);
121    }
122    subInfo = GetSubInitInfo(INIT_CONTEXT_MAIN);
123    if (subInfo != nullptr) {
124        EXPECT_EQ(1, 0);
125    }
126}
127
128HWTEST_F(InitContextUnitTest, InitSubContextTest_04, TestSize.Level1)
129{
130    int ret = StartSubInit(INIT_CONTEXT_CHIPSET);
131    EXPECT_EQ(ret, 0);
132    if (g_thread != 0) {
133        pthread_join(g_thread, nullptr);
134        g_thread = 0;
135    }
136    SubInitInfo *subInfo = GetSubInitInfo(INIT_CONTEXT_CHIPSET);
137    if (subInfo != nullptr) {
138        EXPECT_EQ(2, subInfo->state);
139        StopSubInit(subInfo->subPid);
140    } else {
141        EXPECT_EQ(1, 0);
142    }
143    // close
144    subInfo = GetSubInitInfo(INIT_CONTEXT_CHIPSET);
145    if (subInfo != nullptr) {
146        EXPECT_EQ(0, subInfo->state);
147    }
148
149    SubInitContext *subContext = GetSubInitContext(INIT_CONTEXT_CHIPSET);
150    if (subContext == nullptr) {
151        EXPECT_EQ(0, -1);
152        return;
153    }
154    ret = subContext->executeCmdInSubInit(INIT_CONTEXT_CHIPSET, "mkdir-2", STARTUP_INIT_UT_PATH"/testsubcontext");
155    EXPECT_NE(ret, 0);
156}
157
158HWTEST_F(InitContextUnitTest, InitSubContextTest_05, TestSize.Level1)
159{
160    ConfigContext context = { INIT_CONTEXT_CHIPSET };
161    int ret = ExecuteCmdInSubInit(&context, "mkdir-2", STARTUP_INIT_UT_PATH"/testsubcontext");
162    EXPECT_EQ(ret, 0);
163}
164
165HWTEST_F(InitContextUnitTest, InitSubContextTest_06, TestSize.Level1)
166{
167    ConfigContext context = { INIT_CONTEXT_CHIPSET };
168    int index = 0;
169    const char *cmd = GetMatchCmd("mkdir ", &index);
170    if (cmd == nullptr || strstr(cmd, "mkdir ") == nullptr) {
171        EXPECT_EQ(1, 0);
172        return;
173    }
174    DoCmdByIndex(index, STARTUP_INIT_UT_PATH"/testsubcontext", &context);
175}
176
177HWTEST_F(InitContextUnitTest, InitSubContextTest_07, TestSize.Level1)
178{
179    ConfigContext context = { INIT_CONTEXT_MAIN };
180    int index = 0;
181    const char *cmd = GetMatchCmd("mkdir ", &index);
182    if (cmd == nullptr || strstr(cmd, "mkdir ") == nullptr) {
183        EXPECT_EQ(1, 0);
184        return;
185    }
186    DoCmdByIndex(index, STARTUP_INIT_UT_PATH"/testsubcontext", &context);
187}
188
189HWTEST_F(InitContextUnitTest, InitSubContextTest_09, TestSize.Level1)
190{
191    int ret = SetSubInitContext(nullptr, "serviceName");
192    EXPECT_EQ(ret, -1);
193    ConfigContext context = { INIT_CONTEXT_MAIN };
194    ret = SetSubInitContext(&context, "serviceName");
195    EXPECT_EQ(ret, 0);
196    context = { INIT_CONTEXT_CHIPSET };
197    ret = SetSubInitContext(&context, "serviceName");
198    EXPECT_EQ(ret, 0);
199}
200
201HWTEST_F(InitContextUnitTest, InitSubContextTest_10, TestSize.Level1)
202{
203    int ret = InitSubInitContext(INIT_CONTEXT_MAIN, nullptr);
204    EXPECT_EQ(ret, -1);
205    ret = InitSubInitContext(INIT_CONTEXT_CHIPSET, nullptr);
206    EXPECT_EQ(ret, -1);
207
208    SubInitContext *subContext = GetSubInitContext(INIT_CONTEXT_CHIPSET);
209    if (subContext == nullptr) {
210        EXPECT_EQ(0, -1);
211        return;
212    }
213    ret = subContext->startSubInit(INIT_CONTEXT_MAIN);
214    EXPECT_NE(ret, 0);
215    ret = subContext->executeCmdInSubInit(INIT_CONTEXT_CHIPSET, nullptr, nullptr);
216    EXPECT_NE(ret, 0);
217    ret = subContext->executeCmdInSubInit(INIT_CONTEXT_MAIN, nullptr, nullptr);
218    EXPECT_NE(ret, 0);
219}
220} // namespace init_ut
221