• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 <cerrno>
17 #include <cstdlib>
18 #include <cstring>
19 #include <memory>
20 #include <string>
21 #include <unistd.h>
22 #include <gtest/gtest.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 
26 #include "appspawn_modulemgr.h"
27 #include "appspawn_server.h"
28 #include "appspawn_manager.h"
29 #include "app_spawn_stub.h"
30 #include "app_spawn_test_helper.h"
31 #include "json_utils.h"
32 #include "parameter.h"
33 #include "securec.h"
34 
35 using namespace testing;
36 using namespace testing::ext;
37 using namespace OHOS;
38 
39 namespace OHOS {
40 static AppSpawnTestHelper g_testHelper;
41 class AppSpawnCGroupTest : 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 
CreateTestAppInfo(const char * name)49 static AppSpawnedProcess *CreateTestAppInfo(const char *name)
50 {
51     AppSpawnedProcess *appInfo = reinterpret_cast<AppSpawnedProcess *>(
52         malloc(sizeof(AppSpawnedProcess) + strlen(name) + 1));
53     APPSPAWN_CHECK(appInfo != nullptr, return nullptr, "Failed to create appInfo");
54     appInfo->pid = 33;                 // 33
55     appInfo->uid = 200000 * 200 + 21;  // 200000 200 21
56     appInfo->max = 0;
57     appInfo->exitStatus = 0;
58     int ret = strcpy_s(appInfo->name, strlen(name) + 1, name);
59     APPSPAWN_CHECK(ret == 0,
60         free(appInfo); return nullptr, "Failed to strcpy process name");
61     OH_ListInit(&appInfo->node);
62     return appInfo;
63 }
64 
GetTestCGroupFilePath(const AppSpawnedProcess * appInfo,const char * fileName,char * path,bool create)65 static int GetTestCGroupFilePath(const AppSpawnedProcess *appInfo, const char *fileName, char *path, bool create)
66 {
67     int ret = GetCgroupPath(appInfo, path, PATH_MAX);
68     APPSPAWN_CHECK(ret == 0, return errno, "Failed to get real path errno: %{public}d", errno);
69     (void)CreateSandboxDir(path, 0755);  // 0755 default mode
70     ret = strcat_s(path, PATH_MAX, fileName);
71     APPSPAWN_CHECK(ret == 0, return errno, "Failed to strcat_s errno: %{public}d", errno);
72     if (create) {
73         FILE *file = fopen(path, "w");
74         APPSPAWN_CHECK(file != nullptr, return errno, "Create file fail %{public}s errno: %{public}d", path, errno);
75         fclose(file);
76     }
77     return 0;
78 }
79 
80 HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_001, TestSize.Level0)
81 {
82     int ret = -1;
83     AppSpawnedProcess *appInfo = nullptr;
84     const char name[] = "app-test-001";
85     do {
86         appInfo = CreateTestAppInfo(name);
87         APPSPAWN_CHECK(appInfo != nullptr, break, "Failed to create appInfo");
88         char path[PATH_MAX] = {};
89         ret = GetCgroupPath(appInfo, path, sizeof(path));
90         APPSPAWN_CHECK(ret == 0, break, "Failed to get real path errno: %{public}d", errno);
91         APPSPAWN_CHECK(strstr(path, "200") != nullptr && strstr(path, "33") != nullptr && strstr(path, name) != nullptr,
92             break, "Invalid path: %s", path);
93         ret = 0;
94     } while (0);
95     if (appInfo) {
96         free(appInfo);
97     }
98     ASSERT_EQ(ret, 0);
99 }
100 
101 HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_002, TestSize.Level0)
102 {
103     int ret = -1;
104     AppSpawnedProcess *appInfo = nullptr;
105     AppSpawnContent *content = nullptr;
106     FILE *file = nullptr;
107     const char name[] = "app-test-001";
108     do {
109         char path[PATH_MAX] = {};
110         appInfo = CreateTestAppInfo(name);
111         APPSPAWN_CHECK(appInfo != nullptr, break, "Failed to create appInfo");
112 
113         ret = GetTestCGroupFilePath(appInfo, "cgroup.procs", path, true);
114         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
115         content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
116         APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
117         // spawn prepare process
118         ProcessMgrHookExecute(STAGE_SERVER_APP_ADD, content, appInfo);
119 
120         // add success
121         ret = GetTestCGroupFilePath(appInfo, "cgroup.procs", path, false);
122         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
123         // write pid
124         pid_t pids[] = {100, 101, 102};
125         ret = WriteToFile(path, 0, pids, 3);
126         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
127 
128         ret = -1;
129         file = fopen(path, "r");
130         APPSPAWN_CHECK(file != nullptr, break, "Open file fail %{public}s errno: %{public}d", path, errno);
131         pid_t pid = 0;
132         ret = -1;
133         while (fscanf_s(file, "%d\n", &pid) == 1 && pid > 0) {
134             APPSPAWN_LOGV("pid %{public}d %{public}d", pid, appInfo->pid);
135             if (pid == appInfo->pid) {
136                 ret = 0;
137                 break;
138             }
139         }
140         APPSPAWN_CHECK(ret == 0, break, "Error no pid write to path errno: %{public}d", errno);
141 
142     } while (0);
143     if (appInfo) {
144         free(appInfo);
145     }
146     if (file) {
147         fclose(file);
148     }
149     AppSpawnDestroyContent(content);
150     LE_StopLoop(LE_GetDefaultLoop());
151     LE_CloseLoop(LE_GetDefaultLoop());
152     ASSERT_EQ(ret, 0);
153 }
154 
155 HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_003, TestSize.Level0)
156 {
157     int ret = -1;
158     AppSpawnedProcess *appInfo = nullptr;
159     AppSpawnContent *content = nullptr;
160     const char name[] = "app-test-001";
161     do {
162         char path[PATH_MAX] = {};
163         appInfo = CreateTestAppInfo(name);
164         APPSPAWN_CHECK(appInfo != nullptr, break, "Failed to create appInfo");
165 
166         content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
167         APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
168         ProcessMgrHookExecute(STAGE_SERVER_APP_DIED, content, appInfo);
169         ret = 0;
170     } while (0);
171     if (appInfo) {
172         free(appInfo);
173     }
174     AppSpawnDestroyContent(content);
175     LE_StopLoop(LE_GetDefaultLoop());
176     LE_CloseLoop(LE_GetDefaultLoop());
177     ASSERT_EQ(ret, 0);
178 }
179 
180 HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_004, TestSize.Level0)
181 {
182     int ret = -1;
183     AppSpawnedProcess *appInfo = nullptr;
184     AppSpawnContent *content = nullptr;
185     FILE *file = nullptr;
186     const char name[] = "app-test-001";
187     do {
188         char path[PATH_MAX] = {};
189         appInfo = CreateTestAppInfo(name);
190         APPSPAWN_CHECK(appInfo != nullptr, break, "Failed to create appInfo");
191         appInfo->pid = 44;  // 44 test pid
192 
193         content = AppSpawnCreateContent(NWEBSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_NWEB_SPAWN);
194         APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
195         ProcessMgrHookExecute(STAGE_SERVER_APP_ADD, content, appInfo);
196         // add success
197         ret = GetCgroupPath(appInfo, path, sizeof(path));
198         APPSPAWN_CHECK(ret == 0, break, "Failed to get real path errno: %{public}d", errno);
199         ret = strcat_s(path, sizeof(path), "cgroup.procs");
200         APPSPAWN_CHECK(ret == 0, break, "Failed to strcat_s errno: %{public}d", errno);
201         // do not write for nwebspawn, so no file
202         file = fopen(path, "r");
203         APPSPAWN_CHECK(file == nullptr, break, "Find file %{public}s ", path);
204     } while (0);
205     if (appInfo) {
206         free(appInfo);
207     }
208     if (file) {
209         fclose(file);
210     }
211     AppSpawnDestroyContent(content);
212     LE_StopLoop(LE_GetDefaultLoop());
213     LE_CloseLoop(LE_GetDefaultLoop());
214     ASSERT_EQ(ret, 0);
215 }
216 
217 HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_005, TestSize.Level0)
218 {
219     int ret = -1;
220     AppSpawnedProcess *appInfo = nullptr;
221     AppSpawnContent *content = nullptr;
222     const char name[] = "app-test-001";
223     do {
224         char path[PATH_MAX] = {};
225         appInfo = CreateTestAppInfo(name);
226         APPSPAWN_CHECK(appInfo != nullptr, break, "Failed to create appInfo");
227 
228         content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_NWEB_SPAWN);
229         APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
230         ProcessMgrHookExecute(STAGE_SERVER_APP_DIED, content, appInfo);
231         ret = 0;
232     } while (0);
233     if (appInfo) {
234         free(appInfo);
235     }
236     AppSpawnDestroyContent(content);
237     LE_StopLoop(LE_GetDefaultLoop());
238     LE_CloseLoop(LE_GetDefaultLoop());
239     ASSERT_EQ(ret, 0);
240 }
241 
242 /**
243  * @brief in appspawn service, add and delete app
244  *
245  */
246 HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_006, TestSize.Level0)
247 {
248     int ret = -1;
249     AppSpawnedProcess *appInfo = nullptr;
250     AppSpawnContent *content = nullptr;
251     const char name[] = "app-test-001";
252     do {
253         char path[PATH_MAX] = {};
254         appInfo = CreateTestAppInfo(name);
255         APPSPAWN_CHECK(appInfo != nullptr, break, "Failed to create appInfo");
256 
257         ret = GetTestCGroupFilePath(appInfo, "cgroup.procs", path, true);
258         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
259         content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
260         APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
261         ProcessMgrHookExecute(STAGE_SERVER_APP_ADD, content, appInfo);
262 
263         // add success
264         ret = GetTestCGroupFilePath(appInfo, "cgroup.procs", path, false);
265         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
266         // write pid
267         pid_t pids[] = {100, 101, 102};
268         ret = WriteToFile(path, 0, pids, 3);
269         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
270 
271         AppSpawnedProcess *appInfo2 = CreateTestAppInfo(name);
272         APPSPAWN_CHECK(appInfo2 != nullptr, break, "Failed to create appInfo");
273         OH_ListAddTail(&GetAppSpawnMgr()->appQueue, &appInfo2->node);
274         appInfo2->pid = 102;
275         ProcessMgrHookExecute(STAGE_SERVER_APP_ADD, content, appInfo2);
276         // died
277         ProcessMgrHookExecute(STAGE_SERVER_APP_DIED, content, appInfo);
278         OH_ListRemove(&appInfo2->node);
279         free(appInfo2);
280     } while (0);
281     if (appInfo) {
282         free(appInfo);
283     }
284     AppSpawnDestroyContent(content);
285     LE_StopLoop(LE_GetDefaultLoop());
286     LE_CloseLoop(LE_GetDefaultLoop());
287     ASSERT_EQ(ret, 0);
288 }
289 
290 HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_007, TestSize.Level0)
291 {
292     int ret = -1;
293     AppSpawnedProcess *appInfo = nullptr;
294     const char name[] = "app-test-001";
295     do {
296         appInfo = CreateTestAppInfo(name);
297         APPSPAWN_CHECK(appInfo != nullptr, break, "Failed to create appInfo");
298         char path[PATH_MAX] = {};
299         ret = GetCgroupPath(appInfo, path, -1);
300     } while (0);
301     if (appInfo) {
302         free(appInfo);
303     }
304     ASSERT_NE(ret, 0);
305 }
306 
307 HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_008, TestSize.Level0)
308 {
309     pid_t pids[] = {100, 101, 102};
310     int ret = WriteToFile(nullptr, -1, pids, 3);
311     ASSERT_NE(ret, 0);
312 }
313 
314 HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_009, TestSize.Level0)
315 {
316     int ret = -1;
317     AppSpawnedProcess *appInfo = nullptr;
318     AppSpawnContent *content = nullptr;
319     const char name[] = "app-test-001";
320     do {
321         char path[PATH_MAX] = {};
322         appInfo = CreateTestAppInfo(name);
323         APPSPAWN_CHECK(appInfo != nullptr, break, "Failed to create appInfo");
324 
325         ret = GetTestCGroupFilePath(appInfo, "cgroup.procs", path, true);
326         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
327         content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
328         APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
329         // spawn prepare process
330         ProcessMgrHookExecute(STAGE_SERVER_APP_ADD, content, appInfo);
331 
332         // add success
333         ret = GetTestCGroupFilePath(appInfo, "cgroup.procs", path, false);
334         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
335         // write pid
336         pid_t pids[] = {100, 101, 102, 103};
337         ret = WriteToFile(path, 0, pids, 3);
338 
339     } while (0);
340     if (appInfo) {
341         free(appInfo);
342     }
343     AppSpawnDestroyContent(content);
344     LE_StopLoop(LE_GetDefaultLoop());
345     LE_CloseLoop(LE_GetDefaultLoop());
346     ASSERT_EQ(ret, 0);
347 }
348 
349 HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_010, TestSize.Level0)
350 {
351     int ret = ProcessMgrRemoveApp(nullptr, nullptr);
352     ASSERT_EQ(ret, -1);
353     AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN);
354     ret = ProcessMgrRemoveApp(mgr, nullptr);
355     DeleteAppSpawnMgr(mgr);
356     ASSERT_EQ(ret, -1);
357 }
358 
359 HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_011, TestSize.Level0)
360 {
361     int ret = ProcessMgrAddApp(nullptr, nullptr);
362     ASSERT_EQ(ret, -1);
363     AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN);
364     ret = ProcessMgrAddApp(mgr, nullptr);
365     DeleteAppSpawnMgr(mgr);
366     ASSERT_EQ(ret, -1);
367 }
368 }  // namespace OHOS