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 
20 using namespace std;
21 using namespace testing::ext;
22 
23 extern "C" {
24 struct ForkArgs {
25     int (*childFunc)(const SubInitForkArg *arg);
26     SubInitForkArg args;
27 };
28 static pid_t g_pid = 1000;
29 static pthread_t g_thread = 0;
30 
ThreadFunc(void * arg)31 static 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 
SubInitFork(int (* childFunc)(const SubInitForkArg * arg),const SubInitForkArg * args)42 pid_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 
66 namespace init_ut {
67 class InitContextUnitTest : public testing::Test {
68 public:
SetUpTestCase(void)69     static void SetUpTestCase(void) {};
TearDownTestCase(void)70     static void TearDownTestCase(void) {};
SetUp()71     void SetUp() {};
TearDown()72     void TearDown() {};
73 };
74 
75 HWTEST_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 
85 HWTEST_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 
107 HWTEST_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 
128 HWTEST_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 
158 HWTEST_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 
165 HWTEST_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 
177 HWTEST_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 
189 HWTEST_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 
201 HWTEST_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