/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "directory_ex.h" #include <gtest/gtest.h> #include <fcntl.h> #include <algorithm> #include <iostream> #include <fstream> #include <unistd.h> #include <vector> using namespace testing::ext; using namespace std; namespace OHOS { namespace { class UtilsDirectoryTest : public testing::Test { public : static void SetUpTestCase(void); static void TearDownTestCase(void); void SetUp(); void TearDown(); }; void UtilsDirectoryTest::SetUpTestCase(void) { } void UtilsDirectoryTest::TearDownTestCase(void) { } void UtilsDirectoryTest::SetUp(void) { } void UtilsDirectoryTest::TearDown(void) { } /* * @tc.name: testGetCurrentProcFullFileName001 * @tc.desc: get the directory of directorytest */ HWTEST_F(UtilsDirectoryTest, testGetCurrentProcFullFileName001, TestSize.Level0) { string strBaseName = "/data/test/UtilsDirectoryTest"; string strFilename = GetCurrentProcFullFileName(); EXPECT_EQ(strFilename, strBaseName); } /* * @tc.name: testGetCurrentProcPath001 * @tc.desc: get the path of directorytest */ HWTEST_F(UtilsDirectoryTest, testGetCurrentProcPath001, TestSize.Level0) { string strPathName = "/data/test/"; string strCurPathName = GetCurrentProcPath(); EXPECT_EQ(strCurPathName, strPathName); } /* * @tc.name: testExtractFilePath001 * @tc.desc: get the filename of the path */ HWTEST_F(UtilsDirectoryTest, testExtractFilePath001, TestSize.Level0) { string strFilePath = "/data/test/"; string strPath = ExtractFilePath(GetCurrentProcFullFileName()); EXPECT_EQ(strFilePath, strPath); } /* * @tc.name: testExtractFileName001 * @tc.desc: get the filename of the path */ HWTEST_F(UtilsDirectoryTest, testExtractFileName001, TestSize.Level0) { string strBaseName = "UtilsDirectoryTest"; string strName = ExtractFileName(GetCurrentProcFullFileName()); EXPECT_EQ(strBaseName, strName); } /* * @tc.name: testExtractFileExt001 * @tc.desc: get the filename of the path */ HWTEST_F(UtilsDirectoryTest, testExtractFileExt001, TestSize.Level0) { string strBaseName = "test/test.txt"; string strTypeName = ExtractFileExt(strBaseName); EXPECT_EQ(strTypeName, "txt"); } /* * @tc.name: testExtractFileExt002 * @tc.desc: get the filename of the path and test whether the filename contains "." */ HWTEST_F(UtilsDirectoryTest, testExtractFileExt002, TestSize.Level0) { string strBaseName = "test/test_txt"; string strTypeName = ExtractFileExt(strBaseName); EXPECT_EQ(strTypeName, ""); } /* * @tc.name: testExcludeTrailingPathDelimiter001 * @tc.desc: directory unit test */ HWTEST_F(UtilsDirectoryTest, testExcludeTrailingPathDelimiter001, TestSize.Level0) { string strResult = "data/test/UtilsDirectoryTest"; string strName = ExcludeTrailingPathDelimiter("data/test/UtilsDirectoryTest/"); EXPECT_EQ(strResult, strName); } /* * @tc.name: testIncludeTrailingPathDelimiter001 * @tc.desc: directory unit test */ HWTEST_F(UtilsDirectoryTest, testIncludeTrailingPathDelimiter001, TestSize.Level0) { string strResult = "data/test/UtilsDirectoryTest/"; string strName = IncludeTrailingPathDelimiter("data/test/UtilsDirectoryTest"); EXPECT_EQ(strResult, strName); } /* * @tc.name: testIncludeTrailingPathDelimiter002 * @tc.desc: directory unit test */ HWTEST_F(UtilsDirectoryTest, testIncludeTrailingPathDelimiter002, TestSize.Level0) { string strResult = "/"; string strName = IncludeTrailingPathDelimiter(""); EXPECT_EQ(strResult, strName); } /* * @tc.name: testGetDirFiles001 * @tc.desc: test GetDirFiles works on multi-level directory */ HWTEST_F(UtilsDirectoryTest, testGetDirFiles001, TestSize.Level0) { string parentPath = "/data/test_dir"; ForceCreateDirectory(parentPath); string dirs[6] = { "/data/test_dir/level1_1", "/data/test_dir/level1_2", "/data/test_dir/level1_2/level2_1", "/data/test_dir/level1_2/level2_2", "/data/test_dir/level1_2/level2_2/level3_1", "/data/test_dir/level1_3", }; string resultfiles[9] = { "/data/test_dir/level1_1/test_file", "/data/test_dir/level1_2/level2_2/level3_1/test_file_1", "/data/test_dir/level1_2/level2_2/level3_1/test_file_2", "/data/test_dir/level1_2/level2_2/test_file_1", "/data/test_dir/level1_2/level2_2/test_file_2", "/data/test_dir/level1_2/level2_2/test_file_3", "/data/test_dir/level1_2/level2_2/test_file_4", "/data/test_dir/level1_2/test_file", "/data/test_dir/level1_3/test_file", }; for (auto &path : dirs) { ForceCreateDirectory(path); } for (auto &filepath : resultfiles) { ofstream(filepath, fstream::out); } vector<string> files; GetDirFiles(parentPath, files); for (auto &filepath : resultfiles) { auto pos = find(files.begin(), files.end(), filepath); EXPECT_NE(pos, files.end()); } ForceRemoveDirectory(parentPath); } /* * @tc.name: testGetDirFiles002 * @tc.desc: test GetDirFiles works on deeply nested directory and handles very long path */ HWTEST_F(UtilsDirectoryTest, testGetDirFiles002, TestSize.Level0) { string parentPath = "/data/test_dir/"; string veryLongPath = "/data/test_dir/"; int length = 10000; for (int i = 0; i < length; i++) { veryLongPath += "0"; veryLongPath += "/"; } EXPECT_EQ(mkdir("/data/test_dir", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH), 0); chdir(parentPath.c_str()); for (int i = 0; i < length; i++) { EXPECT_EQ(mkdir("./0", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH), 0); EXPECT_EQ(chdir("./0"), 0); } ofstream file("./test_file"); file.close(); EXPECT_EQ(chdir("/data/test"), 0); auto files = vector<string>(); GetDirFiles(parentPath, files); EXPECT_EQ(files.size(), 1); EXPECT_EQ((veryLongPath + "test_file").length(), files[0].length()); EXPECT_EQ(veryLongPath + "test_file", files[0]); ForceRemoveDirectory(parentPath); } /* * @tc.name: testGetDirFiles003 * @tc.desc: test GetDirFiles works on symlink */ HWTEST_F(UtilsDirectoryTest, testGetDirFiles003, TestSize.Level0) { // create a test dir string originalDataPath = "/data/original"; EXPECT_EQ(ForceCreateDirectory(originalDataPath), true); string originalFilePath = "/data/original/original_file"; string originalDirectoryPath = "/data/original/original_directory"; ofstream(originalFilePath, fstream::out); ForceCreateDirectory(originalDirectoryPath); string testDataDir = "/data/test_dir"; EXPECT_EQ(ForceCreateDirectory(testDataDir), true); // test symlink to directory outside the target directory string linktodir = IncludeTrailingPathDelimiter(testDataDir) + "symlink_dir"; EXPECT_EQ(symlink(originalDirectoryPath.c_str(), linktodir.c_str()), 0); vector<string> dirResult; GetDirFiles(testDataDir, dirResult); EXPECT_EQ(dirResult.size(), 1); EXPECT_EQ(dirResult[0], linktodir); EXPECT_EQ(ForceRemoveDirectory(linktodir), true); // test symlink to file outside the target directory string linktofile = IncludeTrailingPathDelimiter(testDataDir) + "symlink_file"; EXPECT_EQ(symlink(originalFilePath.c_str(), linktofile.c_str()), 0); vector<string> fileResult; GetDirFiles(testDataDir, fileResult); EXPECT_EQ(fileResult.size(), 1); EXPECT_EQ(fileResult[0], linktofile); EXPECT_EQ(RemoveFile(linktofile), true); // test symlink of files in the same directory string sourceFile = IncludeTrailingPathDelimiter(testDataDir) + "source"; string symlinkFile = IncludeTrailingPathDelimiter(testDataDir) + "symlink_file"; ofstream(sourceFile, fstream::out); EXPECT_EQ(symlink(sourceFile.c_str(), symlinkFile.c_str()), 0); vector<string> internalFiles; GetDirFiles(testDataDir, internalFiles); EXPECT_NE(find(internalFiles.begin(), internalFiles.end(), sourceFile), internalFiles.end()); EXPECT_NE(find(internalFiles.begin(), internalFiles.end(), symlinkFile), internalFiles.end()); EXPECT_EQ(RemoveFile(sourceFile), true); EXPECT_EQ(RemoveFile(symlinkFile), true); ForceRemoveDirectory(originalDataPath); ForceRemoveDirectory(testDataDir); } /* * @tc.name: testForceCreateDirectory001 * @tc.desc: directory unit test */ HWTEST_F(UtilsDirectoryTest, testForceCreateDirectory001, TestSize.Level0) { string dirpath = "/data/test_dir/test2/test3"; bool ret = ForceCreateDirectory(dirpath); EXPECT_EQ(ret, true); ret = IsEmptyFolder(dirpath); EXPECT_EQ(ret, true); } /* * @tc.name: testForceRemoveDirectory001 * @tc.desc: directory unit test */ HWTEST_F(UtilsDirectoryTest, testForceRemoveDirectory001, TestSize.Level0) { string dirpath = "/data/test_dir"; bool ret = ForceRemoveDirectory(dirpath); EXPECT_EQ(ret, true); } /* * @tc.name: testForceRemoveDirectory002 * @tc.desc: test whether the folder exists */ HWTEST_F(UtilsDirectoryTest, testForceRemoveDirectory002, TestSize.Level0) { string dirpath = "/data/test/utils_directory_tmp/"; bool ret = ForceRemoveDirectory(dirpath); EXPECT_EQ(ret, false); } /* * @tc.name: testForceRemoveDirectory003 * @tc.desc: test whether it works when the full path is over than 255. */ HWTEST_F(UtilsDirectoryTest, testForceRemoveDirectory003, TestSize.Level0) { string dirpath = "/data/test/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/" "tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/" "tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/" "tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp/tmp"; bool ret = ForceCreateDirectory(dirpath); EXPECT_EQ(ret, true); string rootpath = "/data/test/tmp"; ret = ForceRemoveDirectory(rootpath); EXPECT_EQ(ret, true); } /* * @tc.name: testRemoveFile001 * @tc.desc: directory unit test */ HWTEST_F(UtilsDirectoryTest, testRemoveFile001, TestSize.Level0) { string dirpath = "/data/test_dir"; bool ret = ForceCreateDirectory(dirpath); EXPECT_EQ(ret, true); string filename = dirpath + "/test.txt"; FILE *fp = fopen(filename.c_str(), "w"); if (NULL != fp) { fclose(fp); ret = RemoveFile(filename); EXPECT_EQ(ret, true); } ret = ForceRemoveDirectory(dirpath); EXPECT_EQ(ret, true); } /* * @tc.name: testRemoveFile002 * @tc.desc: Remove soft link file. */ HWTEST_F(UtilsDirectoryTest, testRemoveFile002, TestSize.Level0) { string dirpath = "/data/test_dir"; bool ret = ForceCreateDirectory(dirpath); EXPECT_EQ(ret, true); string targetname = "/data/test_target.txt"; FILE *fp = fopen(targetname.c_str(), "w"); if (NULL != fp) { fclose(fp); } // symlink to a directory string linkpath = "/data/test_symlink_dir"; int res = symlink(dirpath.c_str(), linkpath.c_str()); EXPECT_EQ(res, 0); ret = ForceRemoveDirectory(linkpath); EXPECT_EQ(ret, true); // Target dir is not removed. ret = faccessat(AT_FDCWD, dirpath.c_str(), F_OK, AT_SYMLINK_NOFOLLOW); EXPECT_EQ(ret, 0); // symlink to a file string filename = dirpath + "/test.txt"; res = symlink(targetname.c_str(), filename.c_str()); EXPECT_EQ(res, 0); ret = ForceRemoveDirectory(dirpath); EXPECT_EQ(ret, true); // Target file is not removed. ret = faccessat(AT_FDCWD, targetname.c_str(), F_OK, AT_SYMLINK_NOFOLLOW); EXPECT_EQ(ret, 0); ret = RemoveFile(targetname); EXPECT_EQ(ret, true); } /* * @tc.name: testRemoveFile003 * @tc.desc: Remove dangling soft link file. */ HWTEST_F(UtilsDirectoryTest, testRemoveFile003, TestSize.Level0) { string dirpath = "/data/test_dir"; bool ret = ForceCreateDirectory(dirpath); EXPECT_EQ(ret, true); // symlink to a file string targetname = "/data/nonexisted.txt"; string filename = dirpath + "/test.txt"; int res = symlink(targetname.c_str(), filename.c_str()); EXPECT_EQ(res, 0); ret = ForceRemoveDirectory(dirpath); EXPECT_EQ(ret, true); ret = RemoveFile(targetname); EXPECT_EQ(ret, true); } /* * @tc.name: testGetFolderSize001 * @tc.desc: directory unit test */ HWTEST_F(UtilsDirectoryTest, testGetFolderSize001, TestSize.Level0) { string dirpath = "/data/test_folder/"; bool ret = ForceCreateDirectory(dirpath); EXPECT_EQ(ret, true); ofstream out(dirpath + "test.txt"); if (out.is_open()) { out << "This is a line.\n"; out << "This is another line.\n"; out.close(); } uint64_t resultsize = GetFolderSize(dirpath); uint64_t resultcomp = 38; EXPECT_EQ(resultsize, resultcomp); mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; ret = ChangeModeFile(dirpath + "test.txt", mode); EXPECT_EQ(ret, true); mode = S_IRUSR | S_IRGRP | S_IROTH; ret = ChangeModeDirectory(dirpath, mode); EXPECT_EQ(ret, true); ret = ForceRemoveDirectory(dirpath); EXPECT_EQ(ret, true); } /* * @tc.name: testChangeModeFile001 * @tc.desc: test whether the folder exists */ HWTEST_F(UtilsDirectoryTest, testChangeModeFile001, TestSize.Level0) { string dirpath = "/data/test/utils_directory_tmp/"; mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; bool ret = ChangeModeFile(dirpath + "test.txt", mode); EXPECT_EQ(ret, false); } /* * @tc.name: testChangeModeDirectory001 * @tc.desc: test whether the folder is empty and get the size of the folder */ HWTEST_F(UtilsDirectoryTest, testChangeModeDirectory001, TestSize.Level0) { string dirpath = ""; mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; bool ret = ChangeModeDirectory(dirpath, mode); EXPECT_EQ(ret, false); uint64_t resultsize = GetFolderSize(dirpath); uint64_t resultcomp = 0; EXPECT_EQ(resultsize, resultcomp); } /* * @tc.name: testPathToRealPath001 * @tc.desc: directory unit test */ HWTEST_F(UtilsDirectoryTest, testPathToRealPath001, TestSize.Level0) { string path = "/data/test"; string realpath; bool ret = PathToRealPath(path, realpath); EXPECT_EQ(ret, true); EXPECT_EQ(path, realpath); } /* * @tc.name: testPathToRealPath002 * @tc.desc: directory unit test */ HWTEST_F(UtilsDirectoryTest, testPathToRealPath002, TestSize.Level0) { string path = "/data/../data/test"; string realpath; bool ret = PathToRealPath(path, realpath); EXPECT_EQ(ret, true); EXPECT_EQ("/data/test", realpath); } /* * @tc.name: testPathToRealPath003 * @tc.desc: directory unit test */ HWTEST_F(UtilsDirectoryTest, testPathToRealPath003, TestSize.Level0) { string path = "./"; string realpath; bool ret = PathToRealPath(path, realpath); EXPECT_EQ(ret, true); EXPECT_EQ("/data/test", realpath); } /* * @tc.name: testPathToRealPath004 * @tc.desc: directory unit test */ HWTEST_F(UtilsDirectoryTest, testPathToRealPath004, TestSize.Level0) { string path = ""; string realpath; bool ret = PathToRealPath(path, realpath); EXPECT_EQ(ret, false); } /* * @tc.name: testPathToRealPath005 * @tc.desc: directory unit test */ HWTEST_F(UtilsDirectoryTest, testPathToRealPath005, TestSize.Level0) { string path = "/data/test/data/test/data/test/data/test/data/test/data/ \ test/data/test/data/test/data/test/data/test/data/test/data/test/data/ \ test/data/test/data/test/data/test/data/test/data/test/data/test/data/ \ test/data/test/data/test/data/test/data/test/data/test/data/test/data/ \ test/data/test/data/test/data/test"; string realpath; bool ret = PathToRealPath(path, realpath); EXPECT_EQ(ret, false); } /* * @tc.name: testPathToRealPath006 * @tc.desc: test whether the folder exists */ HWTEST_F(UtilsDirectoryTest, testPathToRealPath006, TestSize.Level0) { string path(PATH_MAX, 'x'); string realpath; bool ret = PathToRealPath(path, realpath); EXPECT_EQ(ret, false); } } // namespace } // namespace OHOS