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 29using namespace std; 30using namespace testing::ext; 31 32namespace init_ut { 33static const std::string SRC_FILE_PATH = STARTUP_INIT_UT_PATH"/eng/source/test.txt"; 34static const std::string TARGET_PATH = STARTUP_INIT_UT_PATH"/eng/link_name"; 35static const std::string ENG_ROOT_PATH = STARTUP_INIT_UT_PATH"/eng/"; 36 37static 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 70static 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 82static 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 94class EngUnitTest : public testing::Test { 95public: 96 static void SetUpTestCase(void) {}; 97 static void TearDownTestCase(void) {}; 98 void SetUp() {}; 99 void TearDown() {}; 100}; 101 102HWTEST_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 139HWTEST_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 180HWTEST_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 188HWTEST_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 243HWTEST_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