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