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