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
94 class EngUnitTest : public testing::Test {
95 public:
SetUpTestCase(void)96 static void SetUpTestCase(void) {};
TearDownTestCase(void)97 static void TearDownTestCase(void) {};
SetUp()98 void SetUp() {};
TearDown()99 void TearDown() {};
100 };
101
102 HWTEST_F(EngUnitTest, TestFilesOverlay, TestSize.Level1)
103 {
104 bool isDel = false;
105 bool isExist = IsDirExist(ENG_ROOT_PATH.c_str());
106 if (isExist) {
107 isDel = RemoveDir(ENG_ROOT_PATH.c_str());
108 EXPECT_EQ(isDel, true);
109 }
110 isExist = IsDirExist(TARGET_PATH.c_str());
111 if (isExist) {
112 isDel = RemoveDir(TARGET_PATH.c_str());
113 EXPECT_EQ(isDel, true);
114 }
115 DebugFilesOverlay(ENG_ROOT_PATH.c_str(), TARGET_PATH.c_str());
116
117 CreateTestFile(SRC_FILE_PATH.c_str(), "test");
118 isExist = IsFileExist(SRC_FILE_PATH.c_str());
119 EXPECT_EQ(isExist, true);
120
121 DebugFilesOverlay(SRC_FILE_PATH.c_str(), TARGET_PATH.c_str());
122 isExist = IsFileExistWithType(SRC_FILE_PATH.c_str(), TYPE_REG);
123 EXPECT_EQ(isExist, true);
124
125
126 if (IsFileExistWithType(TARGET_PATH.c_str(), TYPE_LINK)) {
127 if (unlink(TARGET_PATH.c_str()) < 0) {
128 EXPECT_TRUE(false);
129 }
130 }
131 int ret = symlink(ENG_ROOT_PATH.c_str(), TARGET_PATH.c_str());
132 EXPECT_EQ(ret, 0);
133 isExist = IsFileExistWithType(TARGET_PATH.c_str(), TYPE_LINK);
134 EXPECT_EQ(isExist, true);
135 DebugFilesOverlay(TARGET_PATH.c_str(), ENG_ROOT_PATH.c_str());
136 EXPECT_EQ(ret, 0);
137 }
138
139 HWTEST_F(EngUnitTest, TestBindMountFile, TestSize.Level1)
140 {
141 BindMountFile("data/init_ut", "");
142 BindMountFile("data", "target");
143 BindMountFile("/data/init_ut//", "/");
144 BindMountFile("/data/init_ut", "/");
145 BindMountFile("/data", "/");
146 BindMountFile("/data/", "/");
147
148 bool isExist = false;
149 if (!IsFileExist(SRC_FILE_PATH.c_str())) {
150 CreateTestFile(SRC_FILE_PATH.c_str(), "test reg file mount");
151 isExist = IsFileExist(SRC_FILE_PATH.c_str());
152 EXPECT_EQ(isExist, true);
153 BindMountFile(SRC_FILE_PATH.c_str(), "/");
154 }
155 BindMountFile(SRC_FILE_PATH.c_str(), "/");
156
157 if (IsFileExist(SRC_FILE_PATH.c_str())) {
158 RemoveDir(STARTUP_INIT_UT_PATH"/eng/source");
159 isExist = IsFileExist(SRC_FILE_PATH.c_str());
160 EXPECT_EQ(isExist, false);
161 }
162 if (IsFileExistWithType(TARGET_PATH.c_str(), TYPE_LINK)) {
163 if (unlink(TARGET_PATH.c_str()) < 0) {
164 EXPECT_TRUE(false);
165 }
166 }
167
168 bool isLinkFile = IsFileExist(TARGET_PATH.c_str());
169 EXPECT_EQ(isLinkFile, false);
170 BindMountFile(SRC_FILE_PATH.c_str(), TARGET_PATH.c_str());
171
172 int ret = symlink(SRC_FILE_PATH.c_str(), TARGET_PATH.c_str());
173 EXPECT_EQ(ret, 0);
174 isLinkFile = IsFileExistWithType(TARGET_PATH.c_str(), TYPE_LINK);
175 EXPECT_EQ(isLinkFile, true);
176 BindMountFile(SRC_FILE_PATH.c_str(), TARGET_PATH.c_str());
177 BindMountFile(TARGET_PATH.c_str(), SRC_FILE_PATH.c_str());
178 }
179
180 HWTEST_F(EngUnitTest, TestMountCmd, TestSize.Level1)
181 {
182 char mountCmd[MOUNT_CMD_MAX_LEN] = {};
183 MountEngPartitions();
184 BuildMountCmd(mountCmd, MOUNT_CMD_MAX_LEN, "/eng/source", "/eng/target", "ext4");
185 BuildMountCmd(mountCmd, 0, "/eng/source", "/eng/target", "ext4");
186 }
187
188 HWTEST_F(EngUnitTest, TestFileType, TestSize.Level1)
189 {
190 std::string targetFile = "/data/init_ut/eng/target_file";
191 std::string linkName = "/data/init_ut/eng/link_name_test";
192 bool isExist = false;
193
194 if (!IsFileExist(SRC_FILE_PATH.c_str())) {
195 CreateTestFile(SRC_FILE_PATH.c_str(), "test");
196 isExist = IsFileExist(SRC_FILE_PATH.c_str());
197 EXPECT_EQ(isExist, true);
198 }
199
200 EXPECT_EQ(IsFileExistWithType(SRC_FILE_PATH.c_str(), TYPE_REG), true);
201 EXPECT_EQ(IsFileExistWithType(STARTUP_INIT_UT_PATH"/eng", TYPE_DIR), true);
202
203 EXPECT_EQ(IsFileExistWithType(STARTUP_INIT_UT_PATH"/eng", TYPE_LINK), false);
204 EXPECT_EQ(IsFileExistWithType(STARTUP_INIT_UT_PATH"/eng", TYPE_REG), false);
205 EXPECT_EQ(IsFileExistWithType(STARTUP_INIT_UT_PATH"/eng", TYPE_ANY), true);
206 EXPECT_EQ(IsFileExistWithType(SRC_FILE_PATH.c_str(), TYPE_DIR), false);
207
208 if (IsFileExist(targetFile)) {
209 if (unlink(targetFile.c_str()) < 0) {
210 std::cout << "Failed to unlink file " << targetFile << " err = " << errno << std::endl;
211 EXPECT_TRUE(false);
212 }
213 }
214 int fd = open(targetFile.c_str(), O_CREAT | O_CLOEXEC | O_WRONLY, 0644);
215 if (fd < 0) {
216 std::cout << "Failed to create file " << targetFile << " err = " << errno << std::endl;
217 EXPECT_TRUE(false);
218 } else {
219 std::string buffer = "hello";
220 write(fd, buffer.c_str(), buffer.size());
221 close(fd); // avoid leak
222 }
223
224 if (IsFileExist(linkName)) {
225 if (unlink(linkName.c_str()) < 0) {
226 std::cout << "Failed to unlink file " << linkName << " err = " << errno << std::endl;
227 EXPECT_TRUE(false);
228 }
229 }
230
231 int ret = symlink(targetFile.c_str(), linkName.c_str());
232 EXPECT_EQ(ret, 0);
233 bool isFileExist = IsFileExistWithType(linkName.c_str(), TYPE_LINK);
234 EXPECT_EQ(isFileExist, true);
235
236 isFileExist = IsFileExistWithType("/eng/target", TYPE_LINK);
237 EXPECT_EQ(isFileExist, false);
238
239 isFileExist = IsFileExistWithType("/eng/target", TYPE_REG);
240 EXPECT_EQ(isFileExist, false);
241 }
242
243 HWTEST_F(EngUnitTest, TestHook, TestSize.Level1)
244 {
245 HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
246 PrepareCmdLineData();
247 HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
248 const char *cmdLine = "ohos.boot.root_package=off ";
249 CreateTestFile(BOOT_CMD_LINE, cmdLine);
250 HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
251 }
252 } // namespace init_ut
253