• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <iostream>
17 #include <unistd.h>
18 #include <fcntl.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <dirent.h>
22 
23 #include "init_eng.h"
24 #include "init_utils.h"
25 #include "param_stub.h"
26 #include "bootstage.h"
27 #include "securec.h"
28 
29 using namespace std;
30 using namespace testing::ext;
31 
32 namespace init_ut {
33 static const std::string SRC_FILE_PATH = STARTUP_INIT_UT_PATH"/eng/source/test.txt";
34 static const std::string TARGET_PATH = STARTUP_INIT_UT_PATH"/eng/link_name";
35 static const std::string ENG_ROOT_PATH = STARTUP_INIT_UT_PATH"/eng/";
36 
RemoveDir(const std::string & path)37 static bool RemoveDir(const std::string &path)
38 {
39     if (path.empty()) {
40         return false;
41     }
42     std::string strPath = path;
43     if (strPath.at(strPath.length() - 1) != '/') {
44         strPath.append("/");
45     }
46     DIR *d = opendir(strPath.c_str());
47     if (d != nullptr) {
48         struct dirent *dt = nullptr;
49         dt = readdir(d);
50         while (dt != nullptr) {
51             if (strcmp(dt->d_name, "..") == 0 || strcmp(dt->d_name, ".") == 0) {
52                 dt = readdir(d);
53                 continue;
54             }
55             struct stat st {};
56             auto file_name = strPath + std::string(dt->d_name);
57             stat(file_name.c_str(), &st);
58             if (S_ISDIR(st.st_mode)) {
59                 RemoveDir(file_name);
60             } else {
61                 remove(file_name.c_str());
62             }
63             dt = readdir(d);
64         }
65         closedir(d);
66     }
67     return rmdir(strPath.c_str()) == 0 ? true : false;
68 }
69 
IsFileExist(const std::string & path)70 static bool IsFileExist(const std::string &path)
71 {
72     if (path.empty()) {
73         return false;
74     }
75     struct stat st {};
76     if (stat(path.c_str(), &st) == 0 && S_ISREG(st.st_mode)) {
77         return true;
78     }
79     return false;
80 }
81 
IsDirExist(const std::string & path)82 static bool IsDirExist(const std::string &path)
83 {
84     if (path.empty()) {
85         return false;
86     }
87     struct stat st {};
88     if (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) {
89         return true;
90     }
91     return false;
92 }
93 
TestBuildMountCmd(char * buffer,size_t len,const char * mp,const char * dev,const char * fstype)94 static int TestBuildMountCmd(char *buffer, size_t len, const char *mp, const char *dev, const char *fstype)
95 {
96     BuildMountCmd(buffer, len, mp, dev, fstype);
97     return 0;
98 }
99 
100 class EngUnitTest : public testing::Test {
101 public:
SetUpTestCase(void)102     static void SetUpTestCase(void) {};
TearDownTestCase(void)103     static void TearDownTestCase(void) {};
SetUp()104     void SetUp() {};
TearDown()105     void TearDown() {};
106 };
107 
108 HWTEST_F(EngUnitTest, TestFilesOverlay, TestSize.Level1)
109 {
110     bool isDel = false;
111     bool isExist = IsDirExist(ENG_ROOT_PATH.c_str());
112     if (isExist) {
113         isDel = RemoveDir(ENG_ROOT_PATH.c_str());
114         EXPECT_EQ(isDel, true);
115     }
116     isExist = IsDirExist(TARGET_PATH.c_str());
117     if (isExist) {
118         isDel = RemoveDir(TARGET_PATH.c_str());
119         EXPECT_EQ(isDel, true);
120     }
121     DebugFilesOverlay(ENG_ROOT_PATH.c_str(), TARGET_PATH.c_str());
122 
123     CreateTestFile(SRC_FILE_PATH.c_str(), "test");
124     isExist = IsFileExist(SRC_FILE_PATH.c_str());
125     EXPECT_EQ(isExist, true);
126 
127     DebugFilesOverlay(SRC_FILE_PATH.c_str(), TARGET_PATH.c_str());
128     isExist = IsFileExistWithType(SRC_FILE_PATH.c_str(), TYPE_REG);
129     EXPECT_EQ(isExist, true);
130 
131 
132     if (IsFileExistWithType(TARGET_PATH.c_str(), TYPE_LINK)) {
133         if (unlink(TARGET_PATH.c_str()) < 0) {
134             EXPECT_TRUE(false);
135         }
136     }
137     int ret = symlink(ENG_ROOT_PATH.c_str(), TARGET_PATH.c_str());
138     EXPECT_EQ(ret, 0);
139     isExist = IsFileExistWithType(TARGET_PATH.c_str(), TYPE_LINK);
140     EXPECT_EQ(isExist, true);
141     DebugFilesOverlay(TARGET_PATH.c_str(), ENG_ROOT_PATH.c_str());
142     EXPECT_EQ(ret, 0);
143 }
144 
145 HWTEST_F(EngUnitTest, TestBindMountFile, TestSize.Level1)
146 {
147     BindMountFile("data/init_ut", "");
148     BindMountFile("data", "target");
149     BindMountFile("/data/init_ut//", "/");
150     BindMountFile("/data/init_ut", "/");
151     BindMountFile("/data", "/");
152     BindMountFile("/data/", "/");
153 
154     bool isExist = false;
155     if (!IsFileExist(SRC_FILE_PATH.c_str())) {
156         CreateTestFile(SRC_FILE_PATH.c_str(), "test reg file mount");
157         isExist = IsFileExist(SRC_FILE_PATH.c_str());
158         EXPECT_EQ(isExist, true);
159         BindMountFile(SRC_FILE_PATH.c_str(), "/");
160     }
161     BindMountFile(SRC_FILE_PATH.c_str(), "/");
162 
163     if (IsFileExist(SRC_FILE_PATH.c_str())) {
164         RemoveDir(STARTUP_INIT_UT_PATH"/eng/source");
165         isExist = IsFileExist(SRC_FILE_PATH.c_str());
166         EXPECT_EQ(isExist, false);
167     }
168     if (IsFileExistWithType(TARGET_PATH.c_str(), TYPE_LINK)) {
169         if (unlink(TARGET_PATH.c_str()) < 0) {
170             EXPECT_TRUE(false);
171         }
172     }
173 
174     bool isLinkFile = IsFileExist(TARGET_PATH.c_str());
175     EXPECT_EQ(isLinkFile, false);
176     BindMountFile(SRC_FILE_PATH.c_str(), TARGET_PATH.c_str());
177 
178     int ret = symlink(SRC_FILE_PATH.c_str(), TARGET_PATH.c_str());
179     EXPECT_EQ(ret, 0);
180     isLinkFile = IsFileExistWithType(TARGET_PATH.c_str(), TYPE_LINK);
181     EXPECT_EQ(isLinkFile, true);
182     BindMountFile(SRC_FILE_PATH.c_str(), TARGET_PATH.c_str());
183     BindMountFile(TARGET_PATH.c_str(), SRC_FILE_PATH.c_str());
184 }
185 
186 HWTEST_F(EngUnitTest, TestMountCmd, TestSize.Level1)
187 {
188     char mountCmd[MOUNT_CMD_MAX_LEN] = {};
189     MountEngPartitions();
190     int ret = TestBuildMountCmd(mountCmd, MOUNT_CMD_MAX_LEN, "/eng/source", "/eng/target", "ext4");
191     EXPECT_EQ(ret, 0);
192     ret = TestBuildMountCmd(mountCmd, 0, "/eng/source", "/eng/target", "ext4");
193     EXPECT_EQ(ret, 0);
194 }
195 
196 HWTEST_F(EngUnitTest, TestFileType, TestSize.Level1)
197 {
198     std::string targetFile = "/data/init_ut/eng/target_file";
199     std::string linkName = "/data/init_ut/eng/link_name_test";
200     bool isExist = false;
201 
202     if (!IsFileExist(SRC_FILE_PATH.c_str())) {
203         CreateTestFile(SRC_FILE_PATH.c_str(), "test");
204         isExist = IsFileExist(SRC_FILE_PATH.c_str());
205         EXPECT_EQ(isExist, true);
206     }
207 
208     EXPECT_EQ(IsFileExistWithType(SRC_FILE_PATH.c_str(), TYPE_REG), true);
209     EXPECT_EQ(IsFileExistWithType(STARTUP_INIT_UT_PATH"/eng", TYPE_DIR), true);
210 
211     EXPECT_EQ(IsFileExistWithType(STARTUP_INIT_UT_PATH"/eng", TYPE_LINK), false);
212     EXPECT_EQ(IsFileExistWithType(STARTUP_INIT_UT_PATH"/eng", TYPE_REG), false);
213     EXPECT_EQ(IsFileExistWithType(STARTUP_INIT_UT_PATH"/eng", TYPE_ANY), true);
214     EXPECT_EQ(IsFileExistWithType(SRC_FILE_PATH.c_str(), TYPE_DIR), false);
215 
216     if (IsFileExist(targetFile)) {
217         if (unlink(targetFile.c_str()) < 0) {
218             std::cout << "Failed to unlink file " << targetFile << " err = " << errno << std::endl;
219             EXPECT_TRUE(false);
220         }
221     }
222     int fd = open(targetFile.c_str(), O_CREAT | O_CLOEXEC | O_WRONLY, 0644);
223     if (fd < 0) {
224         std::cout << "Failed to create file " << targetFile << " err = " << errno << std::endl;
225         EXPECT_TRUE(false);
226     } else {
227         std::string buffer = "hello";
228         write(fd, buffer.c_str(), buffer.size());
229         close(fd); // avoid leak
230     }
231 
232     if (IsFileExist(linkName)) {
233         if (unlink(linkName.c_str()) < 0) {
234             std::cout << "Failed to unlink file " << linkName << " err = " << errno << std::endl;
235             EXPECT_TRUE(false);
236         }
237     }
238 
239     int ret = symlink(targetFile.c_str(), linkName.c_str());
240     EXPECT_EQ(ret, 0);
241     bool isFileExist = IsFileExistWithType(linkName.c_str(), TYPE_LINK);
242     EXPECT_EQ(isFileExist, true);
243 
244     isFileExist = IsFileExistWithType("/eng/target", TYPE_LINK);
245     EXPECT_EQ(isFileExist, false);
246 
247     isFileExist = IsFileExistWithType("/eng/target", TYPE_REG);
248     EXPECT_EQ(isFileExist, false);
249 }
250 
251 HWTEST_F(EngUnitTest, TestHook, TestSize.Level1)
252 {
253     int ret = HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
254     EXPECT_NE(ret, -1);
255     PrepareCmdLineData();
256     ret = HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
257     EXPECT_NE(ret, -1);
258     const char *cmdLine = "ohos.boot.root_package=off ";
259     CreateTestFile(BOOT_CMD_LINE, cmdLine);
260     ret = HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
261     EXPECT_NE(ret, -1);
262 }
263 } // namespace init_ut
264