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 <cstdlib>
17 #include <cstring>
18 #include <string>
19 #include <unistd.h>
20 
21 #include <gtest/gtest.h>
22 #include <sys/ipc.h>
23 #include <sys/shm.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 
27 #include "appspawn_modulemgr.h"
28 #include "appspawn_server.h"
29 #include "appspawn_manager.h"
30 #include "json_utils.h"
31 #include "parameter.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 using namespace OHOS;
40 
41 namespace OHOS {
42 
43 class AppSpawnColdRunTest : public testing::Test {
44 public:
SetUpTestCase()45     static void SetUpTestCase() {}
TearDownTestCase()46     static void TearDownTestCase()
47     {
48         StubNode *stub = GetStubNode(STUB_MOUNT);
49         if (stub) {
50             stub->flags &= ~STUB_NEED_CHECK;
51         }
52     }
SetUp()53     void SetUp()
54     {
55         testServer = std::make_unique<OHOS::AppSpawnTestServer>("appspawn -mode appspawn");
56         if (testServer != nullptr) {
57             testServer->Start(nullptr);
58         }
59     }
TearDown()60     void TearDown()
61     {
62         if (testServer != nullptr) {
63             testServer->Stop();
64         }
65     }
66 public:
67     std::unique_ptr<OHOS::AppSpawnTestServer> testServer = nullptr;
68 };
69 
70 /**
71  * 接管启动的exec 过程
72  *
73  */
ExecvAbortStub(const char * pathName,char * const argv[])74 static int ExecvAbortStub(const char *pathName, char *const argv[])
75 {
76     if (!(strcmp(pathName, "/system/bin/appspawn") == 0 || strcmp(pathName, "/system/asan/bin/appspawn") == 0)) {
77         return 0;
78     }
79     APPSPAWN_LOGV("ExecvAbortStub pathName: %{public}s ", pathName);
80     _exit(0x7f);
81     return 0;
82 }
83 
ExecvLocalProcessStub(const char * pathName,char * const argv[])84 int ExecvLocalProcessStub(const char *pathName, char *const argv[])
85 {
86     if (!(strcmp(pathName, "/system/bin/appspawn") == 0 || strcmp(pathName, "/system/asan/bin/appspawn") == 0)) {
87         return 0;
88     }
89     APPSPAWN_LOGV("ExecvLocalProcessStub pathName: %{public}s ", pathName);
90     return 0;
91 }
92 
ExecvTimeoutStub(const char * pathName,char * const argv[])93 static int ExecvTimeoutStub(const char *pathName, char *const argv[])
94 {
95     if (!(strcmp(pathName, "/system/bin/appspawn") == 0 || strcmp(pathName, "/system/asan/bin/appspawn") == 0)) {
96         return 0;
97     }
98     APPSPAWN_LOGV("ExecvLocalProcessStub pathName: %{public}s ", pathName);
99     usleep(500000);  // 500000 500ms
100     return 0;
101 }
102 
HandleExecvStub(const char * pathName,char * const argv[])103 static int HandleExecvStub(const char *pathName, char *const argv[])
104 {
105     if (!(strcmp(pathName, "/system/bin/appspawn") == 0 || strcmp(pathName, "/system/asan/bin/appspawn") == 0)) {
106         return 0;
107     }
108     std::string cmd;
109     int index = 0;
110     do {
111         cmd += argv[index];
112         cmd += " ";
113         index++;
114     } while (argv[index] != nullptr);
115     APPSPAWN_LOGV("HandleExecvStub cmd: %{public}s ", cmd.c_str());
116 
117     CmdArgs *args = nullptr;
118     AppSpawnContent *content = AppSpawnTestHelper::StartSpawnServer(cmd, args);
119     if (content == nullptr) {
120         free(args);
121         return -1;
122     }
123     content->runAppSpawn(content, args->argc, args->argv);
124     free(args);
125     APPSPAWN_LOGV("HandleExecvStub %{public}s exit", pathName);
126     _exit(0x7f); // 0x7f user exit
127     return 0;
128 }
129 
130 HWTEST_F(AppSpawnColdRunTest, App_Spawn_Cold_Run_001, TestSize.Level0)
131 {
132     int ret = 0;
133     AppSpawnClientHandle clientHandle = nullptr;
134     StubNode *node = GetStubNode(STUB_EXECV);
135     ASSERT_NE(node != nullptr, 0);
136     do {
137         ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
138         APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME);
139         AppSpawnReqMsgHandle reqHandle = testServer->CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
140         // set cold start flags
141         AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_COLD_BOOT);
142 
143         ret = -1;
144         node->flags |= STUB_NEED_CHECK;
145         node->arg = reinterpret_cast<void *>(HandleExecvStub);
146         AppSpawnResult result = {};
147         ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
148         APPSPAWN_LOGV("App_Spawn_Cold_Run_001 Kill pid %{public}d %{public}d", result.pid, result.result);
149         if (ret == 0 && result.pid > 0) {
150             kill(result.pid, SIGKILL);
151         }
152         ret = 0;
153     } while (0);
154     AppSpawnClientDestroy(clientHandle);
155     ASSERT_EQ(ret, 0);
156 }
157 
158 HWTEST_F(AppSpawnColdRunTest, App_Spawn_Cold_Run_002, TestSize.Level0)
159 {
160     int ret = 0;
161     AppSpawnClientHandle clientHandle = nullptr;
162     StubNode *node = GetStubNode(STUB_EXECV);
163     ASSERT_NE(node != nullptr, 0);
164     do {
165         ret = AppSpawnClientInit(NWEBSPAWN_SERVER_NAME, &clientHandle);
166         APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", NWEBSPAWN_SERVER_NAME);
167         AppSpawnReqMsgHandle reqHandle = testServer->CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
168         // set cold start flags
169         AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_COLD_BOOT);
170 
171         ret = -1;
172         node->flags |= STUB_NEED_CHECK;
173         node->arg = reinterpret_cast<void *>(HandleExecvStub);
174         AppSpawnResult result = {};
175         ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
176         APPSPAWN_LOGV("App_Spawn_Cold_Run_002 Kill pid %{public}d %{public}d", result.pid, result.result);
177         if (ret == 0 && result.pid > 0) {
178             kill(result.pid, SIGKILL);
179         }
180         ret = 0;
181     } while (0);
182     AppSpawnClientDestroy(clientHandle);
183     node->flags &= ~STUB_NEED_CHECK;
184     ASSERT_EQ(ret, 0);
185 }
186 
187 /**
188  * @brief 测试子进程abort
189  *
190  */
191 HWTEST_F(AppSpawnColdRunTest, App_Spawn_Cold_Run_003, TestSize.Level0)
192 {
193     // child abort
194     int ret = 0;
195     AppSpawnClientHandle clientHandle = nullptr;
196     StubNode *node = GetStubNode(STUB_EXECV);
197     ASSERT_NE(node != nullptr, 0);
198     do {
199         ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
200         APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME);
201         AppSpawnReqMsgHandle reqHandle = testServer->CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
202         // set cold start flags
203         AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_COLD_BOOT);
204 
205         ret = -1;
206         node->flags |= STUB_NEED_CHECK;
207         node->arg = reinterpret_cast<void *>(ExecvAbortStub);
208         AppSpawnResult result = {};
209         ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
210         APPSPAWN_LOGV("App_Spawn_Cold_Run_003 Kill pid %{public}d %{public}d", result.pid, result.result);
211         if (ret == 0 && result.pid > 0) {
212             kill(result.pid, SIGKILL);
213         }
214         ret = 0;
215     } while (0);
216     AppSpawnClientDestroy(clientHandle);
217     node->flags &= ~STUB_NEED_CHECK;
218     ASSERT_EQ(ret, 0);
219 }
220 
221 /**
222  * @brief 测试子进程不回复,导致等到超时
223  *
224  */
225 HWTEST_F(AppSpawnColdRunTest, App_Spawn_Cold_Run_004, TestSize.Level0)
226 {
227     int ret = 0;
228     AppSpawnClientHandle clientHandle = nullptr;
229     StubNode *node = GetStubNode(STUB_EXECV);
230     ASSERT_NE(node != nullptr, 0);
231     do {
232         ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
233         APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME);
234         AppSpawnReqMsgHandle reqHandle = testServer->CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
235         // set cold start flags
236         AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_COLD_BOOT);
237 
238         ret = -1;
239         node->flags |= STUB_NEED_CHECK;
240         node->arg = reinterpret_cast<void *>(ExecvTimeoutStub);
241         AppSpawnResult result = {};
242         ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
243         APPSPAWN_LOGV("App_Spawn_Cold_Run_004 Kill pid %{public}d %{public}d", result.pid, result.result);
244         if (ret == 0 && result.pid > 0) {
245             kill(result.pid, SIGKILL);
246         }
247         ret = 0;
248     } while (0);
249     AppSpawnClientDestroy(clientHandle);
250     node->flags &= ~STUB_NEED_CHECK;
251     ASSERT_EQ(ret, 0);
252 }
253 
254 }  // namespace OHOS
255