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