1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci 16d9f0492fSopenharmony_ci#include <iostream> 17d9f0492fSopenharmony_ci#include <unistd.h> 18d9f0492fSopenharmony_ci#include <fcntl.h> 19d9f0492fSopenharmony_ci#include <sys/stat.h> 20d9f0492fSopenharmony_ci#include <sys/types.h> 21d9f0492fSopenharmony_ci#include <dirent.h> 22d9f0492fSopenharmony_ci 23d9f0492fSopenharmony_ci#include "init_eng.h" 24d9f0492fSopenharmony_ci#include "init_utils.h" 25d9f0492fSopenharmony_ci#include "param_stub.h" 26d9f0492fSopenharmony_ci#include "bootstage.h" 27d9f0492fSopenharmony_ci#include "securec.h" 28d9f0492fSopenharmony_ci 29d9f0492fSopenharmony_ciusing namespace std; 30d9f0492fSopenharmony_ciusing namespace testing::ext; 31d9f0492fSopenharmony_ci 32d9f0492fSopenharmony_cinamespace init_ut { 33d9f0492fSopenharmony_cistatic const std::string SRC_FILE_PATH = STARTUP_INIT_UT_PATH"/eng/source/test.txt"; 34d9f0492fSopenharmony_cistatic const std::string TARGET_PATH = STARTUP_INIT_UT_PATH"/eng/link_name"; 35d9f0492fSopenharmony_cistatic const std::string ENG_ROOT_PATH = STARTUP_INIT_UT_PATH"/eng/"; 36d9f0492fSopenharmony_ci 37d9f0492fSopenharmony_cistatic bool RemoveDir(const std::string &path) 38d9f0492fSopenharmony_ci{ 39d9f0492fSopenharmony_ci if (path.empty()) { 40d9f0492fSopenharmony_ci return false; 41d9f0492fSopenharmony_ci } 42d9f0492fSopenharmony_ci std::string strPath = path; 43d9f0492fSopenharmony_ci if (strPath.at(strPath.length() - 1) != '/') { 44d9f0492fSopenharmony_ci strPath.append("/"); 45d9f0492fSopenharmony_ci } 46d9f0492fSopenharmony_ci DIR *d = opendir(strPath.c_str()); 47d9f0492fSopenharmony_ci if (d != nullptr) { 48d9f0492fSopenharmony_ci struct dirent *dt = nullptr; 49d9f0492fSopenharmony_ci dt = readdir(d); 50d9f0492fSopenharmony_ci while (dt != nullptr) { 51d9f0492fSopenharmony_ci if (strcmp(dt->d_name, "..") == 0 || strcmp(dt->d_name, ".") == 0) { 52d9f0492fSopenharmony_ci dt = readdir(d); 53d9f0492fSopenharmony_ci continue; 54d9f0492fSopenharmony_ci } 55d9f0492fSopenharmony_ci struct stat st {}; 56d9f0492fSopenharmony_ci auto file_name = strPath + std::string(dt->d_name); 57d9f0492fSopenharmony_ci stat(file_name.c_str(), &st); 58d9f0492fSopenharmony_ci if (S_ISDIR(st.st_mode)) { 59d9f0492fSopenharmony_ci RemoveDir(file_name); 60d9f0492fSopenharmony_ci } else { 61d9f0492fSopenharmony_ci remove(file_name.c_str()); 62d9f0492fSopenharmony_ci } 63d9f0492fSopenharmony_ci dt = readdir(d); 64d9f0492fSopenharmony_ci } 65d9f0492fSopenharmony_ci closedir(d); 66d9f0492fSopenharmony_ci } 67d9f0492fSopenharmony_ci return rmdir(strPath.c_str()) == 0 ? true : false; 68d9f0492fSopenharmony_ci} 69d9f0492fSopenharmony_ci 70d9f0492fSopenharmony_cistatic bool IsFileExist(const std::string &path) 71d9f0492fSopenharmony_ci{ 72d9f0492fSopenharmony_ci if (path.empty()) { 73d9f0492fSopenharmony_ci return false; 74d9f0492fSopenharmony_ci } 75d9f0492fSopenharmony_ci struct stat st {}; 76d9f0492fSopenharmony_ci if (stat(path.c_str(), &st) == 0 && S_ISREG(st.st_mode)) { 77d9f0492fSopenharmony_ci return true; 78d9f0492fSopenharmony_ci } 79d9f0492fSopenharmony_ci return false; 80d9f0492fSopenharmony_ci} 81d9f0492fSopenharmony_ci 82d9f0492fSopenharmony_cistatic bool IsDirExist(const std::string &path) 83d9f0492fSopenharmony_ci{ 84d9f0492fSopenharmony_ci if (path.empty()) { 85d9f0492fSopenharmony_ci return false; 86d9f0492fSopenharmony_ci } 87d9f0492fSopenharmony_ci struct stat st {}; 88d9f0492fSopenharmony_ci if (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) { 89d9f0492fSopenharmony_ci return true; 90d9f0492fSopenharmony_ci } 91d9f0492fSopenharmony_ci return false; 92d9f0492fSopenharmony_ci} 93d9f0492fSopenharmony_ci 94d9f0492fSopenharmony_ciclass EngUnitTest : public testing::Test { 95d9f0492fSopenharmony_cipublic: 96d9f0492fSopenharmony_ci static void SetUpTestCase(void) {}; 97d9f0492fSopenharmony_ci static void TearDownTestCase(void) {}; 98d9f0492fSopenharmony_ci void SetUp() {}; 99d9f0492fSopenharmony_ci void TearDown() {}; 100d9f0492fSopenharmony_ci}; 101d9f0492fSopenharmony_ci 102d9f0492fSopenharmony_ciHWTEST_F(EngUnitTest, TestFilesOverlay, TestSize.Level1) 103d9f0492fSopenharmony_ci{ 104d9f0492fSopenharmony_ci bool isDel = false; 105d9f0492fSopenharmony_ci bool isExist = IsDirExist(ENG_ROOT_PATH.c_str()); 106d9f0492fSopenharmony_ci if (isExist) { 107d9f0492fSopenharmony_ci isDel = RemoveDir(ENG_ROOT_PATH.c_str()); 108d9f0492fSopenharmony_ci EXPECT_EQ(isDel, true); 109d9f0492fSopenharmony_ci } 110d9f0492fSopenharmony_ci isExist = IsDirExist(TARGET_PATH.c_str()); 111d9f0492fSopenharmony_ci if (isExist) { 112d9f0492fSopenharmony_ci isDel = RemoveDir(TARGET_PATH.c_str()); 113d9f0492fSopenharmony_ci EXPECT_EQ(isDel, true); 114d9f0492fSopenharmony_ci } 115d9f0492fSopenharmony_ci DebugFilesOverlay(ENG_ROOT_PATH.c_str(), TARGET_PATH.c_str()); 116d9f0492fSopenharmony_ci 117d9f0492fSopenharmony_ci CreateTestFile(SRC_FILE_PATH.c_str(), "test"); 118d9f0492fSopenharmony_ci isExist = IsFileExist(SRC_FILE_PATH.c_str()); 119d9f0492fSopenharmony_ci EXPECT_EQ(isExist, true); 120d9f0492fSopenharmony_ci 121d9f0492fSopenharmony_ci DebugFilesOverlay(SRC_FILE_PATH.c_str(), TARGET_PATH.c_str()); 122d9f0492fSopenharmony_ci isExist = IsFileExistWithType(SRC_FILE_PATH.c_str(), TYPE_REG); 123d9f0492fSopenharmony_ci EXPECT_EQ(isExist, true); 124d9f0492fSopenharmony_ci 125d9f0492fSopenharmony_ci 126d9f0492fSopenharmony_ci if (IsFileExistWithType(TARGET_PATH.c_str(), TYPE_LINK)) { 127d9f0492fSopenharmony_ci if (unlink(TARGET_PATH.c_str()) < 0) { 128d9f0492fSopenharmony_ci EXPECT_TRUE(false); 129d9f0492fSopenharmony_ci } 130d9f0492fSopenharmony_ci } 131d9f0492fSopenharmony_ci int ret = symlink(ENG_ROOT_PATH.c_str(), TARGET_PATH.c_str()); 132d9f0492fSopenharmony_ci EXPECT_EQ(ret, 0); 133d9f0492fSopenharmony_ci isExist = IsFileExistWithType(TARGET_PATH.c_str(), TYPE_LINK); 134d9f0492fSopenharmony_ci EXPECT_EQ(isExist, true); 135d9f0492fSopenharmony_ci DebugFilesOverlay(TARGET_PATH.c_str(), ENG_ROOT_PATH.c_str()); 136d9f0492fSopenharmony_ci EXPECT_EQ(ret, 0); 137d9f0492fSopenharmony_ci} 138d9f0492fSopenharmony_ci 139d9f0492fSopenharmony_ciHWTEST_F(EngUnitTest, TestBindMountFile, TestSize.Level1) 140d9f0492fSopenharmony_ci{ 141d9f0492fSopenharmony_ci BindMountFile("data/init_ut", ""); 142d9f0492fSopenharmony_ci BindMountFile("data", "target"); 143d9f0492fSopenharmony_ci BindMountFile("/data/init_ut//", "/"); 144d9f0492fSopenharmony_ci BindMountFile("/data/init_ut", "/"); 145d9f0492fSopenharmony_ci BindMountFile("/data", "/"); 146d9f0492fSopenharmony_ci BindMountFile("/data/", "/"); 147d9f0492fSopenharmony_ci 148d9f0492fSopenharmony_ci bool isExist = false; 149d9f0492fSopenharmony_ci if (!IsFileExist(SRC_FILE_PATH.c_str())) { 150d9f0492fSopenharmony_ci CreateTestFile(SRC_FILE_PATH.c_str(), "test reg file mount"); 151d9f0492fSopenharmony_ci isExist = IsFileExist(SRC_FILE_PATH.c_str()); 152d9f0492fSopenharmony_ci EXPECT_EQ(isExist, true); 153d9f0492fSopenharmony_ci BindMountFile(SRC_FILE_PATH.c_str(), "/"); 154d9f0492fSopenharmony_ci } 155d9f0492fSopenharmony_ci BindMountFile(SRC_FILE_PATH.c_str(), "/"); 156d9f0492fSopenharmony_ci 157d9f0492fSopenharmony_ci if (IsFileExist(SRC_FILE_PATH.c_str())) { 158d9f0492fSopenharmony_ci RemoveDir(STARTUP_INIT_UT_PATH"/eng/source"); 159d9f0492fSopenharmony_ci isExist = IsFileExist(SRC_FILE_PATH.c_str()); 160d9f0492fSopenharmony_ci EXPECT_EQ(isExist, false); 161d9f0492fSopenharmony_ci } 162d9f0492fSopenharmony_ci if (IsFileExistWithType(TARGET_PATH.c_str(), TYPE_LINK)) { 163d9f0492fSopenharmony_ci if (unlink(TARGET_PATH.c_str()) < 0) { 164d9f0492fSopenharmony_ci EXPECT_TRUE(false); 165d9f0492fSopenharmony_ci } 166d9f0492fSopenharmony_ci } 167d9f0492fSopenharmony_ci 168d9f0492fSopenharmony_ci bool isLinkFile = IsFileExist(TARGET_PATH.c_str()); 169d9f0492fSopenharmony_ci EXPECT_EQ(isLinkFile, false); 170d9f0492fSopenharmony_ci BindMountFile(SRC_FILE_PATH.c_str(), TARGET_PATH.c_str()); 171d9f0492fSopenharmony_ci 172d9f0492fSopenharmony_ci int ret = symlink(SRC_FILE_PATH.c_str(), TARGET_PATH.c_str()); 173d9f0492fSopenharmony_ci EXPECT_EQ(ret, 0); 174d9f0492fSopenharmony_ci isLinkFile = IsFileExistWithType(TARGET_PATH.c_str(), TYPE_LINK); 175d9f0492fSopenharmony_ci EXPECT_EQ(isLinkFile, true); 176d9f0492fSopenharmony_ci BindMountFile(SRC_FILE_PATH.c_str(), TARGET_PATH.c_str()); 177d9f0492fSopenharmony_ci BindMountFile(TARGET_PATH.c_str(), SRC_FILE_PATH.c_str()); 178d9f0492fSopenharmony_ci} 179d9f0492fSopenharmony_ci 180d9f0492fSopenharmony_ciHWTEST_F(EngUnitTest, TestMountCmd, TestSize.Level1) 181d9f0492fSopenharmony_ci{ 182d9f0492fSopenharmony_ci char mountCmd[MOUNT_CMD_MAX_LEN] = {}; 183d9f0492fSopenharmony_ci MountEngPartitions(); 184d9f0492fSopenharmony_ci BuildMountCmd(mountCmd, MOUNT_CMD_MAX_LEN, "/eng/source", "/eng/target", "ext4"); 185d9f0492fSopenharmony_ci BuildMountCmd(mountCmd, 0, "/eng/source", "/eng/target", "ext4"); 186d9f0492fSopenharmony_ci} 187d9f0492fSopenharmony_ci 188d9f0492fSopenharmony_ciHWTEST_F(EngUnitTest, TestFileType, TestSize.Level1) 189d9f0492fSopenharmony_ci{ 190d9f0492fSopenharmony_ci std::string targetFile = "/data/init_ut/eng/target_file"; 191d9f0492fSopenharmony_ci std::string linkName = "/data/init_ut/eng/link_name_test"; 192d9f0492fSopenharmony_ci bool isExist = false; 193d9f0492fSopenharmony_ci 194d9f0492fSopenharmony_ci if (!IsFileExist(SRC_FILE_PATH.c_str())) { 195d9f0492fSopenharmony_ci CreateTestFile(SRC_FILE_PATH.c_str(), "test"); 196d9f0492fSopenharmony_ci isExist = IsFileExist(SRC_FILE_PATH.c_str()); 197d9f0492fSopenharmony_ci EXPECT_EQ(isExist, true); 198d9f0492fSopenharmony_ci } 199d9f0492fSopenharmony_ci 200d9f0492fSopenharmony_ci EXPECT_EQ(IsFileExistWithType(SRC_FILE_PATH.c_str(), TYPE_REG), true); 201d9f0492fSopenharmony_ci EXPECT_EQ(IsFileExistWithType(STARTUP_INIT_UT_PATH"/eng", TYPE_DIR), true); 202d9f0492fSopenharmony_ci 203d9f0492fSopenharmony_ci EXPECT_EQ(IsFileExistWithType(STARTUP_INIT_UT_PATH"/eng", TYPE_LINK), false); 204d9f0492fSopenharmony_ci EXPECT_EQ(IsFileExistWithType(STARTUP_INIT_UT_PATH"/eng", TYPE_REG), false); 205d9f0492fSopenharmony_ci EXPECT_EQ(IsFileExistWithType(STARTUP_INIT_UT_PATH"/eng", TYPE_ANY), true); 206d9f0492fSopenharmony_ci EXPECT_EQ(IsFileExistWithType(SRC_FILE_PATH.c_str(), TYPE_DIR), false); 207d9f0492fSopenharmony_ci 208d9f0492fSopenharmony_ci if (IsFileExist(targetFile)) { 209d9f0492fSopenharmony_ci if (unlink(targetFile.c_str()) < 0) { 210d9f0492fSopenharmony_ci std::cout << "Failed to unlink file " << targetFile << " err = " << errno << std::endl; 211d9f0492fSopenharmony_ci EXPECT_TRUE(false); 212d9f0492fSopenharmony_ci } 213d9f0492fSopenharmony_ci } 214d9f0492fSopenharmony_ci int fd = open(targetFile.c_str(), O_CREAT | O_CLOEXEC | O_WRONLY, 0644); 215d9f0492fSopenharmony_ci if (fd < 0) { 216d9f0492fSopenharmony_ci std::cout << "Failed to create file " << targetFile << " err = " << errno << std::endl; 217d9f0492fSopenharmony_ci EXPECT_TRUE(false); 218d9f0492fSopenharmony_ci } else { 219d9f0492fSopenharmony_ci std::string buffer = "hello"; 220d9f0492fSopenharmony_ci write(fd, buffer.c_str(), buffer.size()); 221d9f0492fSopenharmony_ci close(fd); // avoid leak 222d9f0492fSopenharmony_ci } 223d9f0492fSopenharmony_ci 224d9f0492fSopenharmony_ci if (IsFileExist(linkName)) { 225d9f0492fSopenharmony_ci if (unlink(linkName.c_str()) < 0) { 226d9f0492fSopenharmony_ci std::cout << "Failed to unlink file " << linkName << " err = " << errno << std::endl; 227d9f0492fSopenharmony_ci EXPECT_TRUE(false); 228d9f0492fSopenharmony_ci } 229d9f0492fSopenharmony_ci } 230d9f0492fSopenharmony_ci 231d9f0492fSopenharmony_ci int ret = symlink(targetFile.c_str(), linkName.c_str()); 232d9f0492fSopenharmony_ci EXPECT_EQ(ret, 0); 233d9f0492fSopenharmony_ci bool isFileExist = IsFileExistWithType(linkName.c_str(), TYPE_LINK); 234d9f0492fSopenharmony_ci EXPECT_EQ(isFileExist, true); 235d9f0492fSopenharmony_ci 236d9f0492fSopenharmony_ci isFileExist = IsFileExistWithType("/eng/target", TYPE_LINK); 237d9f0492fSopenharmony_ci EXPECT_EQ(isFileExist, false); 238d9f0492fSopenharmony_ci 239d9f0492fSopenharmony_ci isFileExist = IsFileExistWithType("/eng/target", TYPE_REG); 240d9f0492fSopenharmony_ci EXPECT_EQ(isFileExist, false); 241d9f0492fSopenharmony_ci} 242d9f0492fSopenharmony_ci 243d9f0492fSopenharmony_ciHWTEST_F(EngUnitTest, TestHook, TestSize.Level1) 244d9f0492fSopenharmony_ci{ 245d9f0492fSopenharmony_ci HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr); 246d9f0492fSopenharmony_ci PrepareCmdLineData(); 247d9f0492fSopenharmony_ci HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr); 248d9f0492fSopenharmony_ci const char *cmdLine = "ohos.boot.root_package=off "; 249d9f0492fSopenharmony_ci CreateTestFile(BOOT_CMD_LINE, cmdLine); 250d9f0492fSopenharmony_ci HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr); 251d9f0492fSopenharmony_ci} 252d9f0492fSopenharmony_ci} // namespace init_ut 253