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 
23 #include <gtest/gtest.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 "appspawn.h"
31 
32 #include "app_spawn_stub.h"
33 #include "app_spawn_test_helper.h"
34 
35 using namespace testing;
36 using namespace testing::ext;
37 using namespace OHOS;
38 
39 namespace OHOS {
40 static std::string g_ptyName = {};
41 static AppSpawnTestHelper g_testHelper;
42 class AppSpawnBegetCtlTest : public testing::Test {
43 public:
SetUpTestCase()44     static void SetUpTestCase() {}
TearDownTestCase()45     static void TearDownTestCase() {}
SetUp()46     void SetUp() {}
TearDown()47     void TearDown() {}
48 };
49 
InitPtyInterface()50 static void InitPtyInterface()
51 {
52     int pfd = open("/dev/ptmx", O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
53     APPSPAWN_CHECK(pfd >= 0, return, "Failed open pty err=%{public}d", errno);
54     APPSPAWN_CHECK(grantpt(pfd) >= 0, close(pfd); return, "Failed to call grantpt");
55     APPSPAWN_CHECK(unlockpt(pfd) >= 0, close(pfd); return, "Failed to call unlockpt");
56     char ptsbuffer[128] = {0};
57     int ret = ptsname_r(pfd, ptsbuffer, sizeof(ptsbuffer));
58     APPSPAWN_CHECK(ret >= 0, close(pfd);
59         return, "Failed to get pts name err=%{public}d", errno);
60     APPSPAWN_LOGI("ptsbuffer is %{public}s", ptsbuffer);
61     APPSPAWN_CHECK(chmod(ptsbuffer, S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) == 0, close(pfd);
62         return, "Failed to chmod %{public}s, err=%{public}d", ptsbuffer, errno);
63     g_ptyName = std::string(ptsbuffer);
64 }
65 
TestSendAppspawnCmdMessage(const char * cmd,const char * ptyName)66 static int TestSendAppspawnCmdMessage(const char *cmd, const char *ptyName)
67 {
68     AppSpawnClientHandle clientHandle;
69     int ret = AppSpawnClientInit("AppSpawn", &clientHandle);
70     APPSPAWN_CHECK(ret == 0, return -1, "AppSpawnClientInit error");
71     AppSpawnReqMsgHandle reqHandle;
72     ret = AppSpawnReqMsgCreate(AppSpawnMsgType::MSG_BEGET_CMD, cmd, &reqHandle);
73     APPSPAWN_CHECK(ret == 0, return -1, "AppSpawnReqMsgCreate error");
74     ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BEGETCTL_BOOT);
75     APPSPAWN_CHECK(ret == 0,  return -1, "AppSpawnReqMsgSetAppFlag error");
76     ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_BEGET_PID, cmd);
77     APPSPAWN_CHECK(ret == 0,  return -1, "add %{public}s request message error", cmd);
78     ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_BEGET_PTY_NAME, ptyName);
79     APPSPAWN_CHECK(ret == 0,  return -1, "add %{public}s request message error", ptyName);
80     AppSpawnResult result = {};
81     ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
82     if (ret == 0 && result.pid > 0) {
83         kill(result.pid, SIGKILL);
84     }
85     AppSpawnClientDestroy(clientHandle);
86     return 0;
87 }
88 
89 HWTEST_F(AppSpawnBegetCtlTest, App_Spawn_BetgetCtl_001, TestSize.Level0)
90 {
91     InitPtyInterface();
92     EXPECT_NE(g_ptyName.c_str(), nullptr);
93     APPSPAWN_LOGI(" ***ptsbuffer is %{public}s", g_ptyName.c_str());
94     int ret = TestSendAppspawnCmdMessage("1111", g_ptyName.c_str());
95     EXPECT_EQ(ret, 0);
96     RunBegetctlBootApp(nullptr, nullptr);
97     RunAppSandbox(nullptr);
98 }
99 
100 HWTEST_F(AppSpawnBegetCtlTest, App_Spawn_BetgetCtl_002, TestSize.Level0)
101 {
102     std::unique_ptr<OHOS::AppSpawnTestServer> testServer =
103         std::make_unique<OHOS::AppSpawnTestServer>("appspawn -mode appspawn");
104     testServer->Start(nullptr);
105     SetSystemEnv();
106     int ret = -1;
107     InitPtyInterface();
108     EXPECT_NE(g_ptyName.c_str(), nullptr);
109     ret = TestSendAppspawnCmdMessage("1008", g_ptyName.c_str());
110     EXPECT_EQ(ret, 0);
111     testServer->KillNWebSpawnServer();
112     testServer->Stop();
113 }
114 
115 HWTEST_F(AppSpawnBegetCtlTest, App_Spawn_BetgetCtl_003, TestSize.Level0)
116 {
117     AppSpawnClientHandle clientHandle = nullptr;
118     AppSpawnReqMsgHandle reqHandle = 0;
119     AppSpawningCtx *property = nullptr;
120     AppSpawnContent *content = nullptr;
121     int ret = -1;
122     do {
123         InitPtyInterface();
124         EXPECT_NE(g_ptyName.c_str(), nullptr);
125         ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
126         APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME);
127         reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_BEGET_CMD, 0);
128         APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", APPSPAWN_SERVER_NAME);
129         char path[PATH_MAX] = {};
130         content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
131         APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
132 
133         ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);  // 预加载,解析sandbox
134 
135         ret = APPSPAWN_ARG_INVALID;
136         ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BEGETCTL_BOOT);
137         APPSPAWN_CHECK(ret == 0,  break, "AppSpawnReqMsgSetAppFlag error");
138         ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_BEGET_PID, "1008");
139         APPSPAWN_CHECK(ret == 0,  break, "add app pid request message error");
140         ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_BEGET_PTY_NAME, g_ptyName.c_str());
141         APPSPAWN_CHECK(ret == 0,  break, "add %{public}s request message error", g_ptyName.c_str());
142         property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
143         reqHandle = nullptr;
144         APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
145 
146         // spawn prepare process
147         AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
148 
149         // spawn
150         ret = AppSpawnChild(content, &property->client);
151         property = nullptr;
152     } while (0);
153     DeleteAppSpawningCtx(property);
154     AppSpawnReqMsgFree(reqHandle);
155     AppSpawnClientDestroy(clientHandle);
156     ASSERT_EQ(ret, 0);
157 }
158 
159 HWTEST_F(AppSpawnBegetCtlTest, App_Spawn_BetgetCtl_004, TestSize.Level0)
160 {
161     AppSpawnClientHandle clientHandle = nullptr;
162     AppSpawnReqMsgHandle reqHandle = 0;
163     AppSpawningCtx *property = nullptr;
164     int ret = -1;
165     do {
166         // add default
167         AddDefaultVariable();
168 
169         // create msg
170         ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
171         APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME);
172         reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_BEGET_CMD, 0);
173         APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", APPSPAWN_SERVER_NAME);
174 
175         (void)AppSpawnReqMsgSetAppFlag(reqHandle, MAX_FLAGS_INDEX);
176         AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_BEGET_PTY_NAME, nullptr);
177 
178         property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
179         APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
180     } while (0);
181     DeleteAppSpawningCtx(property);
182     AppSpawnClientDestroy(clientHandle);
183     ASSERT_EQ(ret, 0);
184 }
185 }  // namespace OHOS
186