1 /*
2  * Copyright (c) 2021-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 <sys/types.h>
17 
18 #include <cerrno>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <cstring>
22 #include <ctime>
23 #include <vector>
24 
25 #include "gtest/gtest.h"
26 #include "appspawn_message.h"
27 #include "appspawn_service.h"
28 
29 using namespace testing::ext;
30 
AppSpawnFork(int (* childFunc)(void * arg),void * args)31 pid_t AppSpawnFork(int (*childFunc)(void *arg), void *args)
32 {
33     pid_t pid = fork();
34     if (pid == 0) {
35         childFunc((void *)args);
36         _exit(0x7f); // 0x7f user exit
37     }
38     return pid;
39 }
40 
41 namespace OHOS {
42 const unsigned int MALLOC_TEST_LENGTH = 10;
43 const long NANOSECONDS_PER_SECOND = 1000000000;
44 const int TEST_UID = 999;
45 const int TEST_GID = 888;
46 std::vector<std::string> g_badStrings;
47 std::vector<std::string> g_goodStrings;
48 
49 class AppSpawnLiteTest : public testing::Test {
50 public:
SetUpTestCase()51     static void SetUpTestCase()
52     {
53         // empty
54         g_badStrings.push_back(std::string(""));
55         // not json
56         g_badStrings.push_back(std::string("abcdefghijklmnopqrstuvwxyz"));
57         g_badStrings.push_back(std::string("0123456789876543210"));
58         g_badStrings.push_back(std::string("xxxx"));
59         g_badStrings.push_back(std::string("xxxxssssssssssssssssssss"));
60         g_badStrings.push_back(std::string("\"\"\"\"\"\"\"\"\"\"\"\"\"\"\""));
61         g_badStrings.push_back(std::string("............................................."));
62         g_badStrings.push_back(std::string("....%%%....^..***@##.../*--++......$$&&....."));
63         StructuralFormatErrJson();
64         StructuralFieldMisJson();
65         StructuralFieldInvalidJson();
66         printf("[----------] AppSpawnLiteTest, message func test setup.\n");
67     }
68 
TearDownTestCase()69     static void TearDownTestCase()
70     {
71         g_badStrings.clear();
72         g_goodStrings.clear();
73         printf("[----------] AppSpawnLiteTest, message func test teardown.\n");
74     }
SetUp()75     void SetUp() {}
TearDown()76     void TearDown() {}
77 
StructuralFormatErrJson(void)78     static void StructuralFormatErrJson(void)
79     {
80         // looks like json but format error
81         g_badStrings.push_back(std::string(
82             "{bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\":[0]}"));
83         g_badStrings.push_back(std::string(
84             "{\"bundleName:\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\":[0]}"));
85         g_badStrings.push_back(std::string(
86             "{\"bundleName\":\"nameV\",\"identityID:\"1\",\"uID\":10,\"gID\":10,\"capability\":[0]}"));
87         g_badStrings.push_back(std::string(
88             "{\"bundleName\":\"nameV\",\"identityID\":1\",\"uID\":10,\"gID\":10,\"capability\":[0]}"));
89         g_badStrings.push_back(std::string(
90             "{\"bundleName\":\"nameV\",\"identityID\":\"1,\"uID\":10,\"gID\":10,\"capability\":[0]}"));
91         g_badStrings.push_back(std::string(
92             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",uID\":10,\"gID\":10,\"capability\":[0]}"));
93         g_badStrings.push_back(std::string(
94             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID:10,\"gID\":10,\"capability\":[0]}"));
95         g_badStrings.push_back(std::string(
96             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability:[0]}"));
97         g_badStrings.push_back(std::string(
98             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\":[0]}"));
99         g_badStrings.push_back(std::string(
100             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\":0]}"));
101         g_badStrings.push_back(std::string(
102             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\":[0}"));
103         g_badStrings.push_back(std::string(
104             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\":[0]"));
105         g_badStrings.push_back(std::string(
106             "\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\":[0]}"));
107         g_badStrings.push_back(std::string(
108             "{\"bundleName\"\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\":[0]}"));
109         g_badStrings.push_back(std::string(
110             "{\"bundleName\":\"nameV\"\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\":[0]}"));
111         g_badStrings.push_back(std::string(
112             "{\"bundleName\":\"nameV\",\"identityID\"\"1\",\"uID\":10,\"gID\":10,\"capability\":[0]}"));
113         g_badStrings.push_back(std::string(
114             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\"10,\"capability\":[0]}"));
115         g_badStrings.push_back(std::string(
116             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10\"capability\":[0]}"));
117         g_badStrings.push_back(std::string(
118             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\"[0]}"));
119         g_badStrings.push_back(std::string(
120             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\":[0]},"));
121         g_badStrings.push_back(std::string(
122             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\":[0],}"));
123         g_badStrings.push_back(std::string(
124             "{\"bundleName\":\"nameV\",\"identityID\":\"1\",\"uID\":10,\"gID\":10,\"capability\":[0,]}"));
125     }
126 
StructuralFieldMisJson(void)127     static void StructuralFieldMisJson(void)
128     {
129         // json format correct but fields missing
130         g_badStrings.push_back(std::string(
131             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":1000,\"gID\":1000,\"capability\":[0]}"));
132         g_badStrings.push_back(std::string(
133             "{\"\":\"nameV\",\"identityID\":\"1234\",\"uID\":1000,\"gID\":1000,\"capability\":[0]}"));
134         g_badStrings.push_back(std::string(
135             "{\"identityID\":\"1234\",\"uID\":1000,\"gID\":1000,\"capability\":[0]}"));
136         g_badStrings.push_back(std::string(
137             "{\"bundleName\":\"nameV\",\"\":\"1234\",\"uID\":1000,\"gID\":1000,\"capability\":[0]}"));
138         g_badStrings.push_back(std::string(
139             "{\"bundleName\":\"nameV\",\"uID\":1000,\"gID\":1000,\"capability\":[0]}"));
140         g_badStrings.push_back(std::string(
141             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"\":1000,\"gID\":1000,\"capability\":[0]}"));
142         g_badStrings.push_back(std::string(
143             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"gID\":1000,\"capability\":[0]}"));
144         g_badStrings.push_back(std::string(
145             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":1000,\"\":1000,\"capability\":[0]}"));
146         g_badStrings.push_back(std::string(
147             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":1000,\"capability\":[0]}"));
148         g_badStrings.push_back(std::string(
149             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":1000,\"gID\":1000,\"\":[0]}"));
150         g_badStrings.push_back(std::string(
151             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":1000,\"gID\":1000}"));
152     }
153 
StructuralFieldInvalidJson(void)154     static void StructuralFieldInvalidJson(void)
155     {
156         // field value invalid
157         g_badStrings.push_back(std::string(
158             "{\"bundleName\":\"\",\"identityID\":\"1234\",\"uID\":1000,\"gID\":1000,\"capability\":[0]}"));
159         g_badStrings.push_back(std::string(
160             "{\"bundleName\":\"nameV\",\"identityID\":\"\",\"uID\":1000,\"gID\":1000,\"capability\":[0]}"));
161         g_badStrings.push_back(std::string(
162             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":-1000,\"gID\":1000,\"capability\":[0]}"));
163         g_badStrings.push_back(std::string(
164             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":1000,\"gID\":-1000,\"capability\":[-7]}"));
165         g_badStrings.push_back(std::string(
166             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":1000,\"gID\":1000,\"capability\":1}"));
167         g_badStrings.push_back(std::string(
168             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":1000,\"gID\":1000,\"capability\":[0, 3, -9]}"));
169         g_badStrings.push_back(std::string(
170             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":1000,\"gID\":1000,\"capability\":[99999999]}"));
171         g_badStrings.push_back(std::string(
172             "{\"bundleName\":\"nameV\",\"identityID\":1234,\"uID\":1000,\"gID\":1000,\"capability\":[0]}"));
173         g_badStrings.push_back(std::string(
174             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":\"1000\",\"gID\":1000,\"capability\":[0]}"));
175         g_badStrings.push_back(std::string(
176             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":1000,\"gID\":\"1000\",\"capability\":[0]}"));
177         g_badStrings.push_back(std::string(
178             "{\"bundleName\":\"nameV\",\"identityID\":\"1234\",\"uID\":1000,\"gID\":1000,\"capability\":\"0\"}"));
179         g_badStrings.push_back(std::string(
180             "{\"bundleName\": 250,\"identityID\":\"1234\",\"uID\":1000,\"gID\":1000,\"capability\":[0]}"));
181         g_goodStrings.push_back(std::string(
182             "{\"bundleName\":\"testvalid1\",\"identityID\":\"1234\",\"uID\":1000,\"gID\":1000,\"capability\":[0]}"));
183         g_goodStrings.push_back(std::string(
184             "{\"bundleName\":\"testvalid2\",\"identityID\":\"5678\",\"uID\":1001,\"gID\":1001,\"capability\":[3,5]}"));
185         g_goodStrings.push_back(std::string(
186             "{\"bundleName\":\"testvalid3\",\"identityID\":\"91011\",\"uID\":1002,\"gID\":1002,\"capability\":[8,9]}"));
187         g_goodStrings.push_back(std::string(
188             "{\"bundleName\":\"testvalid3\",\"identityID\":\"999\",\"uID\":1002,\"gID\":1002,\"capability\":[]}"));
189         g_goodStrings.push_back(std::string(
190             "{\"bundleName\":\"testvalid3\",\"identityID\":\"3\",\"uID\":1002,\"gID\":1002,\"capability\":[1,2]}"));
191     }
192 };
193 
194 /*
195  ** @tc.name: msgFuncFreeTest_001
196  ** @tc.desc: free message struct function, nullptr test
197  ** @tc.type: FUNC
198  ** @tc.require: AR000F733K
199  ** @tc.author: ZAL
200  **/
201 HWTEST_F(AppSpawnLiteTest, msgFuncFreeTest_001, TestSize.Level1)
202 {
203     // do not crash here
204     FreeMessageSt(nullptr);
205 
206     MessageSt msgSt = {0};
207     FreeMessageSt(&msgSt);
208 
209     EXPECT_EQ(msgSt.bundleName, nullptr);
210     EXPECT_EQ(msgSt.identityID, nullptr);
211     EXPECT_EQ(msgSt.caps, nullptr);
212     EXPECT_EQ(msgSt.uID, -1);
213     EXPECT_EQ(msgSt.gID, -1);
214     EXPECT_EQ(msgSt.capsCnt, 0);
215 }
216 
217 /*
218  ** @tc.name: msgFuncFreeTest_002
219  ** @tc.desc: free message struct function, function test
220  ** @tc.type: FUNC
221  ** @tc.require: AR000F733K
222  ** @tc.author: ZAL
223  **/
224 HWTEST_F(AppSpawnLiteTest, msgFuncFreeTest_002, TestSize.Level1)
225 {
226     MessageSt msgSt = {0};
227 
228     msgSt.capsCnt = MALLOC_TEST_LENGTH;
229     FreeMessageSt(&msgSt);
230     EXPECT_EQ(msgSt.capsCnt, 0);
231 
232     msgSt.uID = TEST_UID;
233     FreeMessageSt(&msgSt);
234     EXPECT_EQ(msgSt.uID, -1);
235 
236     msgSt.gID = TEST_GID;
237     FreeMessageSt(&msgSt);
238     EXPECT_EQ(msgSt.gID, -1);
239 
240     msgSt.bundleName = (char*)malloc(MALLOC_TEST_LENGTH);
241     EXPECT_TRUE(msgSt.bundleName != nullptr);
242     FreeMessageSt(&msgSt);
243     EXPECT_EQ(msgSt.bundleName, nullptr);
244 
245     msgSt.identityID = (char*)malloc(MALLOC_TEST_LENGTH);
246     EXPECT_TRUE(msgSt.identityID != nullptr);
247     FreeMessageSt(&msgSt);
248     EXPECT_EQ(msgSt.identityID, nullptr);
249 
250     msgSt.caps = (unsigned int*)malloc(MALLOC_TEST_LENGTH * sizeof(unsigned int));
251     EXPECT_TRUE(msgSt.caps != nullptr);
252     FreeMessageSt(&msgSt);
253     EXPECT_EQ(msgSt.caps, nullptr);
254 
255     // full test
256     msgSt.bundleName = (char*)malloc(MALLOC_TEST_LENGTH);
257     msgSt.identityID = (char*)malloc(MALLOC_TEST_LENGTH);
258     msgSt.caps = (unsigned int*)malloc(MALLOC_TEST_LENGTH * sizeof(unsigned int));
259     EXPECT_TRUE(msgSt.bundleName != nullptr);
260     EXPECT_TRUE(msgSt.identityID != nullptr);
261     EXPECT_TRUE(msgSt.caps != nullptr);
262 
263     msgSt.capsCnt = MALLOC_TEST_LENGTH;
264     msgSt.uID = TEST_UID;
265     msgSt.gID = TEST_GID;
266 
267     FreeMessageSt(&msgSt);
268     EXPECT_EQ(msgSt.bundleName, nullptr);
269     EXPECT_EQ(msgSt.identityID, nullptr);
270     EXPECT_EQ(msgSt.caps, nullptr);
271     EXPECT_EQ(msgSt.capsCnt, 0);
272     EXPECT_EQ(msgSt.uID, -1);
273     EXPECT_EQ(msgSt.gID, -1);
274 }
275 
GetCurrentTime(struct timespec * tmCur)276 static void GetCurrentTime(struct timespec* tmCur)
277 {
278     if (tmCur == nullptr) {
279         return;
280     }
281     if (clock_gettime(CLOCK_REALTIME, tmCur) != 0) {
282         printf("[----------] AppSpawnLiteTest, get time failed! err %d.\n", errno);
283     }
284 }
285 
286 /*
287  ** @tc.name: msgFuncSplitTest_001
288  ** @tc.desc: split message function, bad strings test
289  ** @tc.type: FUNC
290  ** @tc.require: AR000F733K
291  ** @tc.author: ZAL
292  **/
293 HWTEST_F(AppSpawnLiteTest, msgFuncSplitTest_001, TestSize.Level1)
294 {
295     MessageSt msgSt = {0};
296     EXPECT_NE(SplitMessage(nullptr, 0, nullptr), 0);
297     EXPECT_NE(SplitMessage(nullptr, 0, &msgSt), 0);
298 
299     std::string testMsg = "xxxxxxxx";
300     EXPECT_NE(SplitMessage(testMsg.c_str(), testMsg.length(), nullptr), 0);
301 
302     struct timespec tmStart = {0};
303     GetCurrentTime(&tmStart);
304 
305     for (size_t i = 0; i < g_badStrings.size(); ++i) {
306         int ret = SplitMessage(g_badStrings[i].c_str(), g_badStrings[i].length(), &msgSt);
307         EXPECT_NE(ret, 0);
308         if (ret == 0) {
309             printf("[----------] AppSpawnLiteTest, msgFuncSplitTest_001 i = %u.\n", i);
310             FreeMessageSt(&msgSt);
311         }
312     }
313 
314     struct timespec tmEnd = {0};
315     GetCurrentTime(&tmEnd);
316     long timeUsed = (tmEnd.tv_sec - tmStart.tv_sec) * NANOSECONDS_PER_SECOND + (tmEnd.tv_nsec - tmStart.tv_nsec);
317     printf("[----------] AppSpawnLiteTest, msgFuncSplitTest_001, total time %ld ns, strCnt %u.\n", \
318         timeUsed, g_badStrings.size());
319 }
320 
321 /*
322  ** @tc.name: msgFuncSplitTest_002
323  ** @tc.desc: split message function, good strings test
324  ** @tc.type: FUNC
325  ** @tc.require: AR000F733K
326  ** @tc.author: ZAL
327  **/
328 HWTEST_F(AppSpawnLiteTest, msgFuncSplitTest_002, TestSize.Level1)
329 {
330     MessageSt msgSt = {0};
331 
332     struct timespec tmStart = {0};
333     GetCurrentTime(&tmStart);
334 
335     for (size_t i = 0; i < g_goodStrings.size(); ++i) {
336         int ret = SplitMessage(g_goodStrings[i].c_str(), g_goodStrings[i].length(), &msgSt);
337         EXPECT_EQ(ret, 0);
338         if (ret != 0) {
339             printf("[----------] AppSpawnLiteTest, msgFuncSplitTest_002 i = %u.\n", i);
340         } else {
341             FreeMessageSt(&msgSt);
342         }
343     }
344 
345     struct timespec tmEnd = {0};
346     GetCurrentTime(&tmEnd);
347 
348     long timeUsed = (tmEnd.tv_sec - tmStart.tv_sec) * NANOSECONDS_PER_SECOND + (tmEnd.tv_nsec - tmStart.tv_nsec);
349     printf("[----------] AppSpawnLiteTest, msgFuncSplitTest_002, total time %ld ns, strCnt %u.\n", \
350         timeUsed, g_goodStrings.size());
351 
352     // parse one good string and check all results
353     std::string validStr =
354         "{\"bundleName\":\"validName\",\"identityID\":\"135\",\"uID\":999,\"gID\":888,\"capability\":[0, 1, 5]}";
355     int ret = SplitMessage(validStr.c_str(), validStr.length(), &msgSt);
356     EXPECT_EQ(ret, 0);
357 
358     std::vector<unsigned int> caps;
359     caps.push_back(0);    // 0, test capability
360     caps.push_back(1);    // 1, test capability
361     caps.push_back(5);    // 5, test capability
362 
363     EXPECT_NE(msgSt.bundleName, nullptr);
364     EXPECT_NE(msgSt.identityID, nullptr);
365     EXPECT_EQ(strcmp("validName", msgSt.bundleName), 0);
366     EXPECT_EQ(strcmp("135", msgSt.identityID), 0);
367     EXPECT_EQ(TEST_UID, msgSt.uID);
368     EXPECT_EQ(TEST_GID, msgSt.gID);
369     EXPECT_EQ(caps.size(), msgSt.capsCnt);
370     EXPECT_NE(msgSt.caps, nullptr);
371     for (size_t i = 0; i < caps.size(); ++i) {
372         EXPECT_EQ(caps[i], msgSt.caps[i]);
373     }
374     FreeMessageSt(&msgSt);
375 }
376 
377 HWTEST_F(AppSpawnLiteTest, SetContentFunctionTest_001, TestSize.Level0)
378 {
379     GTEST_LOG_(INFO) << "SetContentFunctionTest_001 start";
380     AppSpawnContent *content = AppSpawnCreateContent("AppSpawn", NULL, 0, 0);
381     SetContentFunction(content);
382 
383     string longProcName = "SetContentFunctionTest_001";
384     int64_t longProcNameLen = longProcName.length();
385 
386     AppSpawnClientLite *liteClient = (AppSpawnClientLite *)malloc(sizeof(AppSpawnClientLite));
387     EXPECT_TRUE(liteClient);
388     liteClient->client.id = 1;
389     liteClient->client.flags = 0;
390 
391     std::string validStr =
392         "{\"bundleName\":\"validName\",\"identityID\":\"135\",\"uID\":999,\"gID\":888,\"capability\":[0, 1, 5]}";
393     int ret = SplitMessage(validStr.c_str(), validStr.length(), &liteClient->message);
394     EXPECT_EQ(ret, 0);
395 
396     ret = AppSpawnExecuteSpawningHook(content, &liteClient->client);
397     EXPECT_EQ(ret, 0);
398 
399     content->runChildProcessor(content, &liteClient->client);
400     free(liteClient);
401     GTEST_LOG_(INFO) << "SetContentFunctionTest_001 end";
402 }
403 }  // namespace OHOS
404