1 /*
2 * Copyright (c) 2024-2024 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 <gtest/gtest.h>
17
18 #include <cstring>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22
23 #include "appspawn.h"
24 #include "appspawn_hook.h"
25 #include "appspawn_manager.h"
26 #include "appspawn_modulemgr.h"
27 #include "appspawn_permission.h"
28 #include "appspawn_sandbox.h"
29 #include "appspawn_utils.h"
30 #include "cJSON.h"
31 #include "json_utils.h"
32 #include "securec.h"
33
34 #include "app_spawn_stub.h"
35 #include "app_spawn_test_helper.h"
36
37 using namespace testing;
38 using namespace testing::ext;
39
40 namespace OHOS {
41 class AppSpawnModuleInterfaceTest : public testing::Test {
42 public:
SetUpTestCase()43 static void SetUpTestCase() {}
TearDownTestCase()44 static void TearDownTestCase() {}
SetUp()45 void SetUp() {}
TearDown()46 void TearDown() {}
47 };
48
49 /**
50 * @brief module interface
51 *
52 */
53 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_AppSpawnModuleMgrInstall_001, TestSize.Level1)
54 {
55 int ret = AppSpawnModuleMgrInstall(nullptr);
56 EXPECT_NE(0, ret);
57 ret = AppSpawnLoadAutoRunModules(MODULE_MAX);
58 EXPECT_NE(0, ret);
59
60 ret = AppSpawnLoadAutoRunModules(MODULE_MAX);
61 EXPECT_NE(0, ret);
62 ret = AppSpawnModuleMgrInstall("/");
63 EXPECT_EQ(0, ret);
64 ret = AppSpawnModuleMgrInstall("");
65 EXPECT_EQ(0, ret);
66 ret = AppSpawnModuleMgrInstall("libappspawn_asan");
67 EXPECT_EQ(0, ret);
68 }
69
70 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_AppSpawnLoadAutoRunModules_001, TestSize.Level1)
71 {
72 int ret = AppSpawnLoadAutoRunModules(MODULE_DEFAULT);
73 EXPECT_EQ(0, ret);
74 AppSpawnModuleMgrUnInstall(MODULE_DEFAULT);
75 ret = AppSpawnLoadAutoRunModules(MODULE_APPSPAWN);
76 EXPECT_EQ(0, ret);
77 ret = AppSpawnLoadAutoRunModules(MODULE_NWEBSPAWN);
78 EXPECT_EQ(0, ret);
79 AppSpawnModuleMgrUnInstall(MODULE_NWEBSPAWN);
80 ret = AppSpawnLoadAutoRunModules(MODULE_COMMON);
81 EXPECT_EQ(0, ret);
82 AppSpawnModuleMgrUnInstall(MODULE_COMMON);
83 ret = AppSpawnLoadAutoRunModules(MODULE_MAX);
84 EXPECT_NE(0, ret);
85 AppSpawnModuleMgrUnInstall(MODULE_MAX);
86 ret = AppSpawnLoadAutoRunModules(100);
87 EXPECT_NE(0, ret);
88 AppSpawnModuleMgrUnInstall(100);
89 }
90
91 /**
92 * @brief hook interface
93 *
94 */
TestAppPreload(AppSpawnMgr * content)95 static int TestAppPreload(AppSpawnMgr *content)
96 {
97 return 0;
98 }
99
100 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_Server_Hook_001, TestSize.Level0)
101 {
102 AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_NWEB_SPAWN);
103 EXPECT_EQ(mgr != nullptr, 1);
104
105 int ret = 0;
106 for (int i = 0; i < STAGE_MAX; i++) {
107 AppSpawnContent *content = reinterpret_cast<AppSpawnContent *>(mgr);
108
109 for (int k = 0; k <= HOOK_PRIO_LOWEST + 1000; k += 1000) { // 1000
110 ret = AddServerStageHook(static_cast<AppSpawnHookStage>(i), k, TestAppPreload);
111 EXPECT_EQ(ret == 0, (i >= STAGE_SERVER_PRELOAD) && (i <= STAGE_SERVER_EXIT));
112 }
113 ret = AddServerStageHook(static_cast<AppSpawnHookStage>(i), 0, nullptr);
114 EXPECT_EQ(ret == 0, 0);
115
116 ret = ServerStageHookExecute(static_cast<AppSpawnHookStage>(i), content);
117 EXPECT_EQ(ret == 0, (i >= STAGE_SERVER_PRELOAD) && (i <= STAGE_SERVER_EXIT));
118
119 ret = ServerStageHookExecute(static_cast<AppSpawnHookStage>(i), nullptr);
120 EXPECT_NE(ret, 0);
121 }
122 DeleteAppSpawnMgr(mgr);
123 }
124
125 /**
126 * @brief AddAppSpawnHook
127 *
128 */
TestAppSpawn(AppSpawnMgr * content,AppSpawningCtx * property)129 static int TestAppSpawn(AppSpawnMgr *content, AppSpawningCtx *property)
130 {
131 return 0;
132 }
133
134 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_App_Spawn_Hook_001, TestSize.Level0)
135 {
136 AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_NWEB_SPAWN);
137 EXPECT_EQ(mgr != nullptr, 1);
138 AppSpawningCtx *appCtx = CreateAppSpawningCtx();
139 EXPECT_EQ(appCtx != nullptr, 1);
140
141 int ret = 0;
142 for (int i = 0; i < STAGE_MAX; i++) {
143 AppSpawnClient *client = reinterpret_cast<AppSpawnClient *>(appCtx);
144 AppSpawnContent *content = reinterpret_cast<AppSpawnContent *>(mgr);
145
146 for (int k = 0; k <= HOOK_PRIO_LOWEST + 1000; k += 1000) { // 1000
147 ret = AddAppSpawnHook(static_cast<AppSpawnHookStage>(i), k, TestAppSpawn);
148 EXPECT_EQ(ret == 0, (i >= STAGE_PARENT_PRE_FORK) && (i <= STAGE_CHILD_PRE_RUN));
149 }
150 ret = AddAppSpawnHook(static_cast<AppSpawnHookStage>(i), 0, nullptr);
151 EXPECT_EQ(ret == 0, 0);
152
153 if (i == STAGE_CHILD_PRE_RUN || i == STAGE_CHILD_EXECUTE) {
154 printf("App_Spawn_App_Spawn_Hook_001 %d \n", i);
155 continue;
156 }
157 ret = AppSpawnHookExecute(static_cast<AppSpawnHookStage>(i), 0, content, client);
158 EXPECT_EQ(ret == 0, (i >= STAGE_PARENT_PRE_FORK) && (i <= STAGE_CHILD_PRE_RUN));
159
160 ret = AppSpawnHookExecute(static_cast<AppSpawnHookStage>(i), 0, nullptr, client);
161 EXPECT_NE(ret, 0);
162
163 ret = AppSpawnHookExecute(static_cast<AppSpawnHookStage>(i), 0, nullptr, nullptr);
164 EXPECT_NE(ret, 0);
165
166 ret = AppSpawnHookExecute(static_cast<AppSpawnHookStage>(i), 0, content, nullptr);
167 EXPECT_NE(ret, 0);
168 }
169 DeleteAppSpawningCtx(appCtx);
170 DeleteAppSpawnMgr(mgr);
171 }
172
173 /**
174 * @brief AddProcessMgrHook
175 *
176 */
ReportProcessExitInfo(const AppSpawnMgr * content,const AppSpawnedProcess * appInfo)177 static int ReportProcessExitInfo(const AppSpawnMgr *content, const AppSpawnedProcess *appInfo)
178 {
179 return 0;
180 }
181
182 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_Process_Hook_001, TestSize.Level0)
183 {
184 AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_NWEB_SPAWN);
185 EXPECT_EQ(mgr != nullptr, 1);
186 AppSpawnedProcess *app = AddSpawnedProcess(1000, "test-001", false);
187 EXPECT_EQ(app != nullptr, 1);
188
189 int ret = 0;
190 for (int i = 0; i < STAGE_MAX; i++) {
191 for (int k = 0; k <= HOOK_PRIO_LOWEST + 1000; k += 1000) { // 1000
192 ret = AddProcessMgrHook(static_cast<AppSpawnHookStage>(i), k, ReportProcessExitInfo);
193 EXPECT_EQ(ret == 0, (i >= STAGE_SERVER_APP_ADD && i <= STAGE_SERVER_APP_UMOUNT));
194 }
195
196 ret = AddProcessMgrHook(static_cast<AppSpawnHookStage>(i), 0, nullptr);
197 EXPECT_EQ(ret == 0, 0);
198
199 ret = ProcessMgrHookExecute(static_cast<AppSpawnHookStage>(i), reinterpret_cast<AppSpawnContent *>(mgr), app);
200 EXPECT_EQ(ret == 0, (i >= STAGE_SERVER_APP_ADD && i <= STAGE_SERVER_APP_UMOUNT));
201
202 ret = ProcessMgrHookExecute(static_cast<AppSpawnHookStage>(i), nullptr, app);
203 EXPECT_NE(ret, 0);
204
205 ret = ProcessMgrHookExecute(static_cast<AppSpawnHookStage>(i), nullptr, nullptr);
206 EXPECT_NE(ret, 0);
207
208 ret = ProcessMgrHookExecute(static_cast<AppSpawnHookStage>(i),
209 reinterpret_cast<AppSpawnContent *>(mgr), nullptr);
210 EXPECT_NE(ret, 0);
211 }
212 TerminateSpawnedProcess(app);
213 DeleteAppSpawnMgr(mgr);
214 }
215
216 /**
217 * @brief RegChildLooper
218 *
219 */
TestChildLoop(AppSpawnContent * content,AppSpawnClient * client)220 static int TestChildLoop(AppSpawnContent *content, AppSpawnClient *client)
221 {
222 return 0;
223 }
224
225 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_RegChildLooper_001, TestSize.Level0)
226 {
227 AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_NWEB_SPAWN);
228 EXPECT_EQ(mgr != nullptr, 1);
229 RegChildLooper(reinterpret_cast<AppSpawnContent *>(mgr), TestChildLoop);
230 RegChildLooper(reinterpret_cast<AppSpawnContent *>(mgr), nullptr);
231 DeleteAppSpawnMgr(mgr);
232 RegChildLooper(nullptr, TestChildLoop);
233 }
234
235 /**
236 * @brief MakeDirRec
237 * int MakeDirRec(const char *path, mode_t mode, int lastPath);
238 */
239 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_MakeDirRec_001, TestSize.Level0)
240 {
241 int ret = MakeDirRec(nullptr, 0, -1);
242 EXPECT_EQ(ret, -1);
243 ret = MakeDirRec(APPSPAWN_BASE_DIR "/test_appspawn/3", 0, 0);
244 EXPECT_EQ(ret, 0);
245 ret = MakeDirRec(APPSPAWN_BASE_DIR "/test_appspawn/1", 0711, 0); // create file
246 EXPECT_EQ(ret, 0);
247 ret = MakeDirRec(APPSPAWN_BASE_DIR "/test_appspawn/2", 0711, 1); // create path
248 EXPECT_EQ(ret, 0);
249 }
250
251 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_DiffTime_001, TestSize.Level0)
252 {
253 struct timespec endTime;
254 struct timespec startTime;
255 clock_gettime(CLOCK_MONOTONIC, &startTime);
256 startTime.tv_sec += 1;
257 clock_gettime(CLOCK_MONOTONIC, &endTime);
258 uint64_t diff = DiffTime(&startTime, &endTime);
259 EXPECT_NE(diff, 0);
260 diff = DiffTime(nullptr, &endTime);
261 EXPECT_EQ(diff, 0);
262 diff = DiffTime(&startTime, nullptr);
263 EXPECT_EQ(diff, 0);
264 }
265
TestSplitStringHandle(const char * str,void * context)266 int TestSplitStringHandle(const char *str, void *context)
267 {
268 static int index = 0;
269 if (index == 3) { // 3 test
270 EXPECT_EQ(strcmp(str, "dddd"), 0);
271 }
272 index++;
273 return 0;
274 }
275
276 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_StringSplit_001, TestSize.Level0)
277 {
278 const char *testStr = "aaaa|bbbb|cccc |dddd| eeee| 1111 | 2222";
279 int ret = StringSplit(testStr, "|", nullptr, TestSplitStringHandle);
280 EXPECT_EQ(ret, 0);
281 ret = StringSplit(testStr, "|", nullptr, nullptr);
282 EXPECT_NE(ret, 0);
283
284 ret = StringSplit(testStr, nullptr, nullptr, TestSplitStringHandle);
285 EXPECT_NE(ret, 0);
286 ret = StringSplit(nullptr, "|", nullptr, TestSplitStringHandle);
287 EXPECT_NE(ret, 0);
288 ret = StringSplit(nullptr, "|", nullptr, nullptr);
289 EXPECT_NE(ret, 0);
290 ret = StringSplit(nullptr, nullptr, nullptr, nullptr);
291 EXPECT_NE(ret, 0);
292 }
293
294 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_GetLastStr_001, TestSize.Level0)
295 {
296 const char *testStr = "aaaa|bbbb|cccc |dddd| eeee| 1111 | 2222";
297 char *tmp = GetLastStr(testStr, "2222");
298 EXPECT_EQ(tmp != nullptr, 1);
299
300 tmp = GetLastStr(testStr, nullptr);
301 EXPECT_EQ(tmp != nullptr, 0);
302
303 tmp = GetLastStr(nullptr, nullptr);
304 EXPECT_EQ(tmp != nullptr, 0);
305 tmp = GetLastStr(nullptr, "2222");
306 EXPECT_EQ(tmp != nullptr, 0);
307 }
308
309 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_DumpCurrentDir_001, TestSize.Level0)
310 {
311 char path[PATH_MAX] = {};
312 DumpCurrentDir(path, sizeof(path), APPSPAWN_BASE_DIR "/test_appspawn/");
313 DumpCurrentDir(path, sizeof(path), nullptr);
314 DumpCurrentDir(path, 0, nullptr);
315 DumpCurrentDir(path, 0, APPSPAWN_BASE_DIR "/test_appspawn/");
316 DumpCurrentDir(nullptr, sizeof(path), APPSPAWN_BASE_DIR "/test_appspawn/");
317 DumpCurrentDir(nullptr, sizeof(path), nullptr);
318 EXPECT_NE(path, nullptr);
319 }
320
TestParseAppSandboxConfig(const cJSON * root,ParseJsonContext * context)321 static int TestParseAppSandboxConfig(const cJSON *root, ParseJsonContext *context)
322 {
323 return 0;
324 }
325
326 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_ParseJsonConfig_001, TestSize.Level0)
327 {
328 int ret = 0;
329 #ifdef APPSPAWN_SANDBOX_NEW
330 ret = ParseJsonConfig("etc/sandbox", WEB_SANDBOX_FILE_NAME, TestParseAppSandboxConfig, nullptr);
331 EXPECT_EQ(ret, 0);
332 ret = ParseJsonConfig("etc/sandbox", APP_SANDBOX_FILE_NAME, TestParseAppSandboxConfig, nullptr);
333 EXPECT_EQ(ret, 0);
334 #else
335 ret = ParseJsonConfig("etc/sandbox", APP_SANDBOX_FILE_NAME, TestParseAppSandboxConfig, nullptr);
336 EXPECT_EQ(ret, 0);
337 #endif
338 ret = ParseJsonConfig("etc/sandbox", APP_SANDBOX_FILE_NAME, nullptr, nullptr);
339 EXPECT_NE(ret, 0);
340 ret = ParseJsonConfig("etc/sandbox", nullptr, TestParseAppSandboxConfig, nullptr);
341 EXPECT_NE(ret, 0);
342 ret = ParseJsonConfig("etc/sandbox", nullptr, nullptr, nullptr);
343 EXPECT_NE(ret, 0);
344 ret = ParseJsonConfig(nullptr, APP_SANDBOX_FILE_NAME, TestParseAppSandboxConfig, nullptr);
345 EXPECT_NE(ret, 0);
346 ret = ParseJsonConfig(nullptr, nullptr, TestParseAppSandboxConfig, nullptr);
347 EXPECT_NE(ret, 0);
348 ret = ParseJsonConfig(nullptr, nullptr, nullptr, nullptr);
349 EXPECT_NE(ret, 0);
350 }
351
352 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_GetJsonObjFromFile_001, TestSize.Level0)
353 {
354 cJSON *json = GetJsonObjFromFile("/etc/sandbox/appdata-sandbox.json");
355 EXPECT_EQ(json != nullptr, 1);
356 cJSON_Delete(json);
357 json = GetJsonObjFromFile(nullptr);
358 EXPECT_EQ(json == nullptr, 1);
359 }
360
361 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_GetStringFromJsonObj_001, TestSize.Level0)
362 {
363 const std::string buffer = "{ \
364 \"global\": { \
365 \"sandbox-root\": \"/mnt/sandbox/<currentUserId>/app-root\", \
366 \"sandbox-ns-flags\": [ \"pid\", \"net\" ], \
367 \"sandbox-flags\": 100, \
368 \"top-sandbox-switch\": \"ON\" \
369 } \
370 }";
371
372 cJSON *json = cJSON_Parse(buffer.c_str());
373 EXPECT_EQ(json != nullptr, 1);
374 char *tmp = GetStringFromJsonObj(cJSON_GetObjectItemCaseSensitive(json, "global"), "sandbox-root");
375 EXPECT_EQ(tmp != nullptr, 1);
376 tmp = GetStringFromJsonObj(cJSON_GetObjectItemCaseSensitive(json, "global"), nullptr);
377 EXPECT_EQ(tmp == nullptr, 1);
378 tmp = GetStringFromJsonObj(nullptr, "sandbox-root");
379 EXPECT_EQ(tmp == nullptr, 1);
380 tmp = GetStringFromJsonObj(nullptr, nullptr);
381 EXPECT_EQ(tmp == nullptr, 1);
382 cJSON_Delete(json);
383 }
384
385 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_GetBoolValueFromJsonObj_001, TestSize.Level0)
386 {
387 const std::string buffer = "{ \
388 \"global\": { \
389 \"sandbox-root\": \"/mnt/sandbox/<currentUserId>/app-root\", \
390 \"sandbox-ns-flags\": [ \"pid\", \"net\" ], \
391 \"sandbox-flags\": 100, \
392 \"top-sandbox-switch\": \"ON\" \
393 } \
394 }";
395
396 cJSON *json = cJSON_Parse(buffer.c_str());
397 EXPECT_EQ(json != nullptr, 1);
398 bool ret = GetBoolValueFromJsonObj(cJSON_GetObjectItemCaseSensitive(json, "global"), "top-sandbox-switch", false);
399 EXPECT_EQ(ret, true);
400 ret = GetBoolValueFromJsonObj(cJSON_GetObjectItemCaseSensitive(json, "global"), nullptr, false);
401 EXPECT_EQ(ret, 0);
402 ret = GetBoolValueFromJsonObj(nullptr, "top-sandbox-switch", false);
403 EXPECT_EQ(ret, 0);
404 ret = GetBoolValueFromJsonObj(nullptr, nullptr, false);
405 EXPECT_EQ(ret, 0);
406 cJSON_Delete(json);
407 }
408
409 HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_GetIntValueFromJsonObj_001, TestSize.Level0)
410 {
411 const std::string buffer = "{ \
412 \"global\": { \
413 \"sandbox-root\": \"/mnt/sandbox/<currentUserId>/app-root\", \
414 \"sandbox-ns-flags\": [ \"pid\", \"net\" ], \
415 \"sandbox-flags\": 100, \
416 \"top-sandbox-switch\": \"ON\" \
417 } \
418 }";
419 cJSON *json = cJSON_Parse(buffer.c_str());
420 EXPECT_EQ(json != nullptr, 1);
421 int tmp = GetIntValueFromJsonObj(cJSON_GetObjectItemCaseSensitive(json, "global"), "sandbox-flags", 0);
422 EXPECT_EQ(tmp, 100);
423 tmp = GetIntValueFromJsonObj(cJSON_GetObjectItemCaseSensitive(json, "global"), nullptr, 0);
424 EXPECT_EQ(tmp, 0);
425 tmp = GetIntValueFromJsonObj(nullptr, "sandbox-flags", 0);
426 EXPECT_EQ(tmp, 0);
427 tmp = GetIntValueFromJsonObj(nullptr, nullptr, 0);
428 EXPECT_EQ(tmp, 0);
429 cJSON_Delete(json);
430 }
431 } // namespace OHOS
432