• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 <cinttypes>
17 #include <sys/mount.h>
18 #include "fs_manager/fs_manager.h"
19 #include "init_log.h"
20 #include "init_param.h"
21 #include "param_stub.h"
22 #include "securec.h"
23 #include "systemcapability.h"
24 #include "service_control.h"
25 #include "control_fd.h"
26 #include "loop_event.h"
27 #include "fd_holder.h"
28 #include "fd_holder_internal.h"
29 
30 using namespace testing::ext;
31 using namespace std;
32 
33 namespace init_ut {
34 
35 extern "C" {
36 void CmdDisConnectComplete(const TaskHandle client);
37 void CmdOnSendMessageComplete(const TaskHandle task, const BufferHandle handle);
38 void CmdOnClose(const TaskHandle task);
39 void CmdOnConnectComplete(const TaskHandle client);
40 void CmdOnRecvMessage(const TaskHandle task, const uint8_t *buffer, uint32_t buffLen);
41 void ProcessPtyRead(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context);
42 void ProcessPtyWrite(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context);
43 int CmdOnIncommingConnect(const LoopHandle loop, const TaskHandle server);
44 CmdAgent *CmdAgentCreate(const char *server);
45 void CmdClientOnRecvMessage(const TaskHandle task, const uint8_t *buffer, uint32_t buffLen);
46 int SendCmdMessage(const CmdAgent *agent, uint16_t type, const char *cmd, const char *ptyName);
47 int SendMessage(LoopHandle loop, TaskHandle task, const char *message);
48 int *GetFdsFromMsg(size_t *outFdCount, pid_t *requestPid, struct msghdr msghdr);
49 int BuildSendData(char *buffer, size_t size, const char *serviceName, bool hold, bool poll);
50 int CheckSocketPermission(const TaskHandle task);
51 }
52 
53 class InnerkitsUnitTest : public testing::Test {
54 public:
SetUpTestCase(void)55     static void SetUpTestCase(void) {};
TearDownTestCase(void)56     static void TearDownTestCase(void) {};
SetUp()57     void SetUp() {};
TearDown()58     void TearDown() {};
59 };
60 
CallbackSendMsgProcessTest(const CmdAgent * agent,uint16_t type,const char * cmd,const char * ptyName)61 static int CallbackSendMsgProcessTest(const CmdAgent *agent, uint16_t type, const char *cmd, const char *ptyName)
62 {
63     return 0;
64 }
65 
TestCmdServiceProcessDelClient(pid_t pid)66 static int TestCmdServiceProcessDelClient(pid_t pid)
67 {
68     CmdServiceProcessDelClient(pid);
69     return 0;
70 }
71 
72 /**
73 * @tc.name: ReadFstabFromFile_unitest
74 * @tc.desc: read fstab from test file.
75 * @tc.type: FUNC
76 * @tc.require:
77 * @tc.author:
78 */
79 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_ReadFstabFromFile001, TestSize.Level1)
80 {
81     Fstab *fstab = nullptr;
82     const std::string fstabFile1 = "/data/fstab.updater1";
83     fstab = ReadFstabFromFile(fstabFile1.c_str(), false);
84     EXPECT_EQ(fstab, nullptr);
85     const std::string fstabFile2 = STARTUP_INIT_UT_PATH"/mount_unitest/ReadFstabFromFile1.fstable";
86     fstab = ReadFstabFromFile(fstabFile2.c_str(), false);
87     EXPECT_NE(fstab, nullptr);
88     ParseFstabPerLine(const_cast<char *>("test"), fstab, true, nullptr);
89     ReleaseFstab(fstab);
90 }
91 
92 /**
93 * @tc.name: FindFstabItemForPath_unitest
94 * @tc.desc: read fstab from test file, then find item according to path.
95 * @tc.type: FUNC
96 * @tc.require:
97 * @tc.author:
98 */
99 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_FindFstabItemForPath001, TestSize.Level1)
100 {
101     const std::string fstabFile1 = STARTUP_INIT_UT_PATH"/mount_unitest/ReadFstabFromFile1.fstable";
102     Fstab *fstab = nullptr;
103     fstab = ReadFstabFromFile(fstabFile1.c_str(), false);
104     ASSERT_NE(fstab, nullptr);
105     FstabItem* item = nullptr;
106     const std::string path1 = "";
107     item = FindFstabItemForPath(*fstab, path1.c_str());
108     if (item == nullptr) {
109         SUCCEED();
110     }
111     const std::string path2 = "/data";
112     item = FindFstabItemForPath(*fstab, path2.c_str());
113     if (item != nullptr) {
114         SUCCEED();
115     }
116     const std::string path3 = "/data2";
117     item = FindFstabItemForPath(*fstab, path3.c_str());
118     if (item == nullptr) {
119         SUCCEED();
120     }
121     const std::string path4 = "/data2/test";
122     item = FindFstabItemForPath(*fstab, path4.c_str());
123     if (item != nullptr) {
124         SUCCEED();
125     }
126     ReleaseFstab(fstab);
127     fstab = nullptr;
128 }
129 
130 /**
131 * @tc.name: FindFstabItemForMountPoint_unitest
132 * @tc.desc: read fstab from test file, then find item that matches with the mount point.
133 * @tc.type: FUNC
134 * @tc.require:
135 * @tc.author:
136 */
137 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_FindFstabItemForMountPoint001, TestSize.Level1)
138 {
139     const std::string fstabFile1 = STARTUP_INIT_UT_PATH"/mount_unitest/ReadFstabFromFile1.fstable";
140     Fstab *fstab = nullptr;
141     fstab = ReadFstabFromFile(fstabFile1.c_str(), false);
142     ASSERT_NE(fstab, nullptr);
143     FstabItem* item = nullptr;
144     const std::string mp1 = "/data";
145     const std::string mp2 = "/data2";
146     item = FindFstabItemForMountPoint(*fstab, mp2.c_str());
147     if (item == nullptr) {
148         SUCCEED();
149     }
150     const std::string mp3 = "/data";
151     item = FindFstabItemForMountPoint(*fstab, mp3.c_str());
152     if (item != nullptr) {
153         SUCCEED();
154     }
155     ReleaseFstab(fstab);
156     fstab = nullptr;
157 }
158 
159 /**
160 * @tc.name: GetMountFlags_unitest
161 * @tc.desc: read fstab from test file, then find the item and get mount flags.
162 * @tc.type: FUNC
163 * @tc.require:
164 * @tc.author:
165 */
166 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_GetMountFlags001, TestSize.Level1)
167 {
168     const std::string fstabFile1 = STARTUP_INIT_UT_PATH"/mount_unitest/ReadFstabFromFile1.fstable";
169     Fstab *fstab = nullptr;
170     fstab = ReadFstabFromFile(fstabFile1.c_str(), true);
171     ASSERT_NE(fstab, nullptr);
172     struct FstabItem* item = nullptr;
173     const std::string mp = "/hos";
174     item = FindFstabItemForMountPoint(*fstab, mp.c_str());
175     if (item == nullptr) {
176         SUCCEED();
177     }
178     const int bufferSize = 512;
179     char fsSpecificOptions[bufferSize] = {0};
180     unsigned long flags = GetMountFlags(item->mountOptions, fsSpecificOptions, bufferSize, item->mountPoint);
181     EXPECT_EQ(flags, static_cast<unsigned long>(MS_NOSUID | MS_NODEV | MS_NOATIME));
182     ReleaseFstab(fstab);
183     fstab = nullptr;
184 }
185 
186 /**
187 * @tc.name: GetSlotInfo_unittest
188 * @tc.desc: get the number of slots and get current slot.
189 * @tc.type: FUNC
190 * @tc.require:issueI5NTX2
191 * @tc.author:
192 */
193 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_GetSlotInfo001, TestSize.Level1)
194 {
195     EXPECT_NE(GetBootSlots(), -1);
196     EXPECT_NE(GetCurrentSlot(), -1);
197 }
198 
199 /**
200 * @tc.name: LoadFstabFromCommandLine_unittest
201 * @tc.desc: get fstab from command line.
202 * @tc.type: FUNC
203 * @tc.require:issueI5NTX2
204 * @tc.author:
205 */
206 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_LoadFstabFromCommandLine001, TestSize.Level1)
207 {
208     EXPECT_NE(LoadFstabFromCommandLine(), (Fstab *)nullptr);
209 }
210 
211 /**
212 * @tc.name: GetBlockDevicePath_unittest
213 * @tc.desc: get block device path according to valid or invalid partition.
214 * @tc.type: FUNC
215 * @tc.require:issueI5NTX2
216 * @tc.author:
217 */
218 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_GetBlockDevicePath001, TestSize.Level1)
219 {
220     char devicePath[MAX_BUFFER_LEN] = {0};
221     EXPECT_EQ(GetBlockDevicePath("/vendor", devicePath, MAX_BUFFER_LEN), 0);
222     EXPECT_EQ(GetBlockDevicePath("/misc", devicePath, MAX_BUFFER_LEN), 0);
223     EXPECT_EQ(GetBlockDevicePath("/invalid", devicePath, MAX_BUFFER_LEN), -1);
224     unlink(BOOT_CMD_LINE);
225     EXPECT_EQ(GetBlockDevicePath("/invalid", devicePath, MAX_BUFFER_LEN), -1);
226     GetCurrentSlot();
227     // restore cmdline
228     PrepareCmdLineData();
229 }
230 
231 /**
232 * @tc.name: DoFormat_unittest
233 * @tc.desc: format file system, includes ext4 and f2fs type.
234 * @tc.type: FUNC
235 * @tc.require:
236 * @tc.author:
237 */
238 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_DoFormat001, TestSize.Level1)
239 {
240     EXPECT_NE(DoFormat("/testpath", "ext4"), -1);
241     EXPECT_NE(DoFormat("/testpath", "f2fs"), -1);
242     EXPECT_EQ(DoFormat("/testpath", "notFs"), -1);
243     EXPECT_EQ(DoFormat(nullptr, nullptr), -1);
244 }
245 
246 /**
247 * @tc.name: MountAllWithFstabFile_unittest
248 * @tc.desc: mount partitions according to fstab that read from file.
249 * @tc.type: FUNC
250 * @tc.require:issueI5NTX2
251 * @tc.author:
252 */
253 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_MountAllWithFstabFile001, TestSize.Level1)
254 {
255     EXPECT_NE(MountAllWithFstabFile(STARTUP_INIT_UT_PATH"/etc/fstab.required", 0), 1);
256     EXPECT_NE(UmountAllWithFstabFile(STARTUP_INIT_UT_PATH"/etc/fstab.required"), 1);
257     EXPECT_EQ(MountAllWithFstabFile("/testErrorFile", 0), -1);
258     EXPECT_EQ(MountAllWithFstabFile(nullptr, 0), -1);
259     EXPECT_EQ(GetMountStatusForMountPoint(nullptr), -1);
260     FstabItem fstabItem = {};
261     fstabItem.fsType = strdup("notSupport");
262     fstabItem.mountPoint = strdup("");
263     EXPECT_EQ(MountOneItem(nullptr), -1);
264     EXPECT_EQ(MountOneItem(&fstabItem), 0);
265     if (fstabItem.fsType != nullptr) {
266         free(fstabItem.fsType);
267         fstabItem.fsType = nullptr;
268     }
269     if (fstabItem.mountPoint != nullptr) {
270         free(fstabItem.mountPoint);
271         fstabItem.mountPoint = nullptr;
272     }
273 }
274 
275 #define SYSCAP_MAX_SIZE 100
276 
277 // TestSysCap
278 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_TestSysCap001, TestSize.Level1)
279 {
280     bool ret = HasSystemCapability("test.cap");
281     EXPECT_EQ(ret, false);
282     ret = HasSystemCapability(nullptr);
283     EXPECT_EQ(ret, false);
284     ret = HasSystemCapability("ArkUI.ArkUI.Napi");
285     EXPECT_EQ(ret, true);
286     ret = HasSystemCapability("SystemCapability.ArkUI.ArkUI.Napi");
287     EXPECT_EQ(ret, true);
288     char *wrongName = reinterpret_cast<char *>(malloc(SYSCAP_MAX_SIZE));
289     ASSERT_NE(wrongName, nullptr);
290     EXPECT_EQ(memset_s(wrongName, SYSCAP_MAX_SIZE, 1, SYSCAP_MAX_SIZE), 0);
291     HasSystemCapability(wrongName);
292     free(wrongName);
293 }
294 
295 // TestControlService
296 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_ControlService001, TestSize.Level1)
297 {
298     TestSetParamCheckResult("startup.service.ctl.", 0777, 0);
299     ServiceControl("deviceinfoservice", START);
300     SystemWriteParam("startup.service.ctl.deviceinfoservice", "2");
301     ServiceControl("deviceinfoservice", RESTART);
302     ServiceControl("deviceinfoservice", STOP);
303     SystemWriteParam("startup.service.ctl.deviceinfoservice", "0");
304     ServiceControl("param_watcher", RESTART);
305     EXPECT_EQ(ServiceControl(nullptr, RESTART), -1);
306     const char *argv[] = {"testArg"};
307     ServiceControlWithExtra("deviceinfoservice", RESTART, argv, 1);
308     ServiceControlWithExtra(nullptr, RESTART, argv, 1);
309     ServiceControlWithExtra(nullptr, 3, argv, 1); // 3 is action
310     ServiceControlWithExtra("notservie", RESTART, argv, 1);
311     ServiceControlWithExtra("deviceinfoservice", 3, argv, 1); // 3 is action
312     ServiceSetReady("deviceinfoservice");
313     ServiceSetReady(nullptr);
314     ServiceWaitForStatus("deviceinfoservice", SERVICE_READY, 1);
315     ServiceWaitForStatus("deviceinfoservice", SERVICE_READY, -1);
316     ServiceWaitForStatus(nullptr, SERVICE_READY, 1);
317     StartServiceByTimer("deviceinfoservice", 1);
318     StartServiceByTimer("deviceinfoservice", 0);
319     StartServiceByTimer(nullptr, 0);
320     StopServiceTimer("deviceinfoservice");
321 }
322 
TestIncommingConnect(const LoopHandle loop,const TaskHandle server)323 static int TestIncommingConnect(const LoopHandle loop, const TaskHandle server)
324 {
325     UNUSED(loop);
326     UNUSED(server);
327     return 0;
328 }
329 
330 // TestControlFd
331 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_ControlFd001, TestSize.Level1)
332 {
333     CmdClientInit("/data/testSock1", ACTION_DUMP, "cmd", nullptr);
334     CmdClientInit("/data/testSock1", ACTION_DUMP, "cmd", CallbackSendMsgProcessTest);
335     CmdClientInit(INIT_CONTROL_FD_SOCKET_PATH, ACTION_DUMP, nullptr, nullptr);
336     CmdClientInit(nullptr, ACTION_DUMP, "cmd", nullptr);
337 
338     CmdDisConnectComplete(nullptr);
339     CmdOnSendMessageComplete(nullptr, nullptr);
340     CmdOnConnectComplete(nullptr);
341     CmdClientOnRecvMessage(nullptr, nullptr, 0);
342     CmdAgentCreate(nullptr);
343     CmdAgent *agent = CmdAgentCreate(INIT_CONTROL_FD_SOCKET_PATH);
344     EXPECT_NE(agent, nullptr);
345     SendCmdMessage(agent, ACTION_DUMP, "cmd", "test");
346     SendCmdMessage(agent, ACTION_DUMP, "cmd", nullptr);
347     SendMessage(nullptr, nullptr, nullptr);
348     uint32_t events = 0;
349     InitPtyInterface(agent, 0, "cmd", nullptr);
350     InitPtyInterface(agent, 0, "cmd", CallbackSendMsgProcessTest);
351     InitPtyInterface(agent, 0, nullptr, nullptr);
352     InitPtyInterface(nullptr, 0, nullptr, nullptr);
353     mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
354     CheckAndCreatFile("/data/init_ut/testInput", mode);
355     int fd = open("/data/init_ut/testInput", O_RDWR);
356     perror("write failed");
357     EXPECT_GT(fd, 0);
358     EXPECT_GT(write(fd, "test", strlen("test")), 0);
359     perror("write failed");
360     lseek(fd, 0, SEEK_SET);
361     ProcessPtyRead(nullptr, fd, &events, (void *)agent);
362     ProcessPtyRead(nullptr, fd, &events, (void *)agent);
363     ProcessPtyRead(nullptr, STDERR_FILENO, &events, nullptr);
364     lseek(fd, 0, SEEK_SET);
365     ProcessPtyWrite(nullptr, fd, &events, (void *)agent);
366     ProcessPtyWrite(nullptr, fd, &events, (void *)agent);
367     ProcessPtyWrite(nullptr, STDERR_FILENO, &events, nullptr);
368     close(fd);
369 
370     if (agent) {
371         CmdOnClose(agent->task);
372     }
373 }
374 
375 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_ControlFdServer001, TestSize.Level1)
376 {
377     CmdServiceInit(nullptr, nullptr, nullptr);
__anon59c35f230102(uint16_t type, const char *serviceCmd, const void *context) 378     CmdServiceInit("/data/testSock1", [](uint16_t type, const char *serviceCmd, const void *context) {
379         UNUSED(type);
380         UNUSED(serviceCmd);
381         UNUSED(context);
382         }, LE_GetDefaultLoop());
383 
384     TaskHandle testServer = nullptr;
385     LE_StreamServerInfo info = {};
386     info.baseInfo.flags = TASK_STREAM | TASK_SERVER | TASK_PIPE | TASK_TEST;
387     info.server = (char *)"/data/testSock1";
388     info.socketId = -1;
389     info.baseInfo.close = nullptr;
390     info.disConnectComplete = nullptr;
391     info.incommingConnect = TestIncommingConnect;
392     info.sendMessageComplete = nullptr;
393     info.recvMessage = nullptr;
394     (void)LE_CreateStreamServer(LE_GetDefaultLoop(), &testServer, &info);
395     CmdOnIncommingConnect(LE_GetDefaultLoop(), testServer);
396 
397     CmdOnRecvMessage(testServer, nullptr, 0);
398     CmdMessage *cmdMsg = (CmdMessage *)malloc(sizeof(CmdMessage) + strlen("test"));
399     cmdMsg->type = ACTION_DUMP;
400     cmdMsg->ptyName[0] = '\0';;
401     CmdOnRecvMessage(testServer, (uint8_t *)(&cmdMsg), 0);
402     cmdMsg->type = ACTION_DUMP;
403     cmdMsg->cmd[0] = 'a';
404     cmdMsg->ptyName[0] = 'a';
405     CmdOnRecvMessage(testServer, (uint8_t *)(&cmdMsg), 0);
406     int ret = TestCmdServiceProcessDelClient(0);
407     EXPECT_EQ(ret, 0);
408     ret = TestCmdServiceProcessDelClient(0);
409     EXPECT_EQ(ret, 0);
410     free(cmdMsg);
411 }
412 
413 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_HoldFd001, TestSize.Level1)
414 {
415     int ret = CheckSocketPermission(nullptr);
416     EXPECT_EQ(ret, -1);
417     CmdServiceProcessDestroyClient();
418 }
419 
420 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_HoldFd002, TestSize.Level1)
421 {
422     int fds1[] = {1, 0};
423     ServiceSaveFd("testServiceName", fds1, ARRAY_LENGTH(fds1));
424     ServiceSaveFd(nullptr, fds1, ARRAY_LENGTH(fds1));
425     ServiceSaveFdWithPoll("testServiceName", fds1, 0);
426     ServiceSaveFdWithPoll(nullptr, fds1, 0);
427     ServiceSaveFdWithPoll("testServiceName", fds1, ARRAY_LENGTH(fds1));
428     EXPECT_EQ(setenv("OHOS_FD_HOLD_testServiceName", "1 0", 0), 0);
429 
430     size_t fdCount = 0;
431     int *fds = nullptr;
432     ServiceGetFd("testService", nullptr);
433     ServiceGetFd("testService", &fdCount);
434     char *wrongName = (char *)malloc(MAX_FD_HOLDER_BUFFER + 1);
435     ASSERT_NE(wrongName, nullptr);
436     EXPECT_EQ(memset_s(wrongName, MAX_FD_HOLDER_BUFFER + 1, 1, MAX_FD_HOLDER_BUFFER + 1), 0);
437     ServiceGetFd(wrongName, &fdCount);
438     BuildSendData(wrongName, 1, "testService", 0, 1);
439     BuildSendData(wrongName, 1, "testService", 0, 0);
440     BuildSendData(nullptr, 1, "testService", 0, 0);
441     free(wrongName);
442 
443     fds = ServiceGetFd("testServiceName", &fdCount);
444     EXPECT_NE(fds, nullptr);
445     struct msghdr msghdr = {};
446     BuildControlMessage(nullptr, nullptr, 1, 0);
447     BuildControlMessage(&msghdr, nullptr, 1, 0);
448     if (msghdr.msg_control != nullptr) {
449         free(msghdr.msg_control);
450         msghdr.msg_control = nullptr;
451     }
452     BuildControlMessage(&msghdr, fds, -1, 0);
453     if (msghdr.msg_control != nullptr) {
454         free(msghdr.msg_control);
455         msghdr.msg_control = nullptr;
456     }
457     BuildControlMessage(&msghdr, fds, -1, 1);
458     if (msghdr.msg_control != nullptr) {
459         free(msghdr.msg_control);
460         msghdr.msg_control = nullptr;
461     }
462     if (fds != nullptr)
463     {
464         free(fds);
465         fds = nullptr;
466     }
467 }
468 
469 HWTEST_F(InnerkitsUnitTest, Init_InnerkitsTest_HoldFd003, TestSize.Level1)
470 {
471     size_t fdCount = 0;
472     int *fds = nullptr;
473     char buffer[MAX_FD_HOLDER_BUFFER + 1] = {};
474     pid_t requestPid = -1;
475     struct msghdr msghdr = {};
476     GetFdsFromMsg(&fdCount, &requestPid, msghdr);
477     msghdr.msg_flags = MSG_TRUNC;
478     int *ret = nullptr;
479     ret = GetFdsFromMsg(&fdCount, &requestPid, msghdr);
480     EXPECT_EQ(ret, nullptr);
481     struct iovec iovec = {
482         .iov_base = buffer,
483         .iov_len = MAX_FD_HOLDER_BUFFER,
484     };
485     ReceiveFds(0, iovec, &fdCount, false, &requestPid);
486     fds = ReceiveFds(0, iovec, &fdCount, true, &requestPid);
487     if (fds != nullptr)
488     {
489         free(fds);
490         fds = nullptr;
491     }
492     if (msghdr.msg_control != nullptr) {
493         free(msghdr.msg_control);
494     }
495 }
496 
497 } // namespace init_ut
498