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