| /* |
| * Copyright (C) 2015 Canon Inc. All rights reserved. |
| * Copyright (C) 2017-2022 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| * THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "config.h" |
| |
| #include "Test.h" |
| #include "Utilities.h" |
| #include <wtf/FileSystem.h> |
| #include <wtf/MainThread.h> |
| #include <wtf/StringExtras.h> |
| |
| namespace TestWebKitAPI { |
| |
| const char* FileSystemTestData = "This is a test"; |
| |
| static void createTestFile(const String& path) |
| { |
| auto fileHandle = FileSystem::openFile(path, FileSystem::FileOpenMode::Write); |
| EXPECT_TRUE(FileSystem::isHandleValid(fileHandle)); |
| FileSystem::writeToFile(fileHandle, FileSystemTestData, strlen(FileSystemTestData)); |
| FileSystem::closeFile(fileHandle); |
| }; |
| |
| // FIXME: Refactor FileSystemTest and FragmentedSharedBufferTest as a single class. |
| class FileSystemTest : public testing::Test { |
| public: |
| void SetUp() override |
| { |
| WTF::initializeMainThread(); |
| |
| // create temp file. |
| FileSystem::PlatformFileHandle handle; |
| m_tempFilePath = FileSystem::openTemporaryFile("tempTestFile"_s, handle); |
| FileSystem::writeToFile(handle, FileSystemTestData, strlen(FileSystemTestData)); |
| FileSystem::closeFile(handle); |
| |
| m_tempFileSymlinkPath = FileSystem::openTemporaryFile("tempTestFile-symlink"_s, handle); |
| FileSystem::closeFile(handle); |
| FileSystem::deleteFile(m_tempFileSymlinkPath); |
| FileSystem::createSymbolicLink(m_tempFilePath, m_tempFileSymlinkPath); |
| |
| // Create temp directory. |
| FileSystem::PlatformFileHandle temporaryFile; |
| m_tempEmptyFolderPath = FileSystem::openTemporaryFile("tempEmptyFolder"_s, temporaryFile); |
| FileSystem::closeFile(temporaryFile); |
| FileSystem::deleteFile(m_tempEmptyFolderPath); |
| FileSystem::makeAllDirectories(m_tempEmptyFolderPath); |
| |
| m_tempEmptyFolderSymlinkPath = FileSystem::openTemporaryFile("tempEmptyFolder-symlink"_s, temporaryFile); |
| FileSystem::closeFile(temporaryFile); |
| FileSystem::deleteFile(m_tempEmptyFolderSymlinkPath); |
| FileSystem::createSymbolicLink(m_tempEmptyFolderPath, m_tempEmptyFolderSymlinkPath); |
| |
| m_tempEmptyFilePath = FileSystem::openTemporaryFile("tempEmptyTestFile"_s, handle); |
| FileSystem::closeFile(handle); |
| |
| m_spaceContainingFilePath = FileSystem::openTemporaryFile("temp Empty Test File"_s, handle); |
| FileSystem::closeFile(handle); |
| |
| m_bangContainingFilePath = FileSystem::openTemporaryFile("temp!Empty!Test!File"_s, handle); |
| FileSystem::closeFile(handle); |
| |
| m_quoteContainingFilePath = FileSystem::openTemporaryFile("temp\"Empty\"TestFile"_s, handle); |
| FileSystem::closeFile(handle); |
| } |
| |
| void TearDown() override |
| { |
| FileSystem::deleteFile(m_tempFilePath); |
| FileSystem::deleteFile(m_tempFileSymlinkPath); |
| FileSystem::deleteNonEmptyDirectory(m_tempEmptyFolderPath); |
| FileSystem::deleteFile(m_tempEmptyFolderSymlinkPath); |
| FileSystem::deleteFile(m_tempEmptyFilePath); |
| FileSystem::deleteFile(m_spaceContainingFilePath); |
| FileSystem::deleteFile(m_bangContainingFilePath); |
| FileSystem::deleteFile(m_quoteContainingFilePath); |
| } |
| |
| const String& tempFilePath() const { return m_tempFilePath; } |
| const String& tempFileSymlinkPath() const { return m_tempFileSymlinkPath; } |
| const String& tempEmptyFolderPath() const { return m_tempEmptyFolderPath; } |
| const String& tempEmptyFolderSymlinkPath() const { return m_tempEmptyFolderSymlinkPath; } |
| const String& tempEmptyFilePath() const { return m_tempEmptyFilePath; } |
| const String& spaceContainingFilePath() const { return m_spaceContainingFilePath; } |
| const String& bangContainingFilePath() const { return m_bangContainingFilePath; } |
| const String& quoteContainingFilePath() const { return m_quoteContainingFilePath; } |
| |
| private: |
| String m_tempFilePath; |
| String m_tempFileSymlinkPath; |
| String m_tempEmptyFolderPath; |
| String m_tempEmptyFolderSymlinkPath; |
| String m_tempEmptyFilePath; |
| String m_spaceContainingFilePath; |
| String m_bangContainingFilePath; |
| String m_quoteContainingFilePath; |
| }; |
| |
| TEST_F(FileSystemTest, MappingMissingFile) |
| { |
| bool success; |
| FileSystem::MappedFileData mappedFileData(String("not_existing_file"_s), FileSystem::MappedFileMode::Shared, success); |
| EXPECT_FALSE(success); |
| EXPECT_TRUE(!mappedFileData); |
| } |
| |
| TEST_F(FileSystemTest, MappingExistingFile) |
| { |
| bool success; |
| FileSystem::MappedFileData mappedFileData(tempFilePath(), FileSystem::MappedFileMode::Shared, success); |
| EXPECT_TRUE(success); |
| EXPECT_TRUE(!!mappedFileData); |
| EXPECT_TRUE(mappedFileData.size() == strlen(FileSystemTestData)); |
| EXPECT_TRUE(strnstr(FileSystemTestData, static_cast<const char*>(mappedFileData.data()), mappedFileData.size())); |
| } |
| |
| TEST_F(FileSystemTest, MappingExistingEmptyFile) |
| { |
| bool success; |
| FileSystem::MappedFileData mappedFileData(tempEmptyFilePath(), FileSystem::MappedFileMode::Shared, success); |
| EXPECT_TRUE(success); |
| EXPECT_TRUE(!mappedFileData); |
| } |
| |
| TEST_F(FileSystemTest, FilesHaveSameVolume) |
| { |
| EXPECT_TRUE(FileSystem::filesHaveSameVolume(tempFilePath(), spaceContainingFilePath())); |
| EXPECT_TRUE(FileSystem::filesHaveSameVolume(spaceContainingFilePath(), bangContainingFilePath())); |
| EXPECT_TRUE(FileSystem::filesHaveSameVolume(bangContainingFilePath(), quoteContainingFilePath())); |
| } |
| |
| TEST_F(FileSystemTest, fileType) |
| { |
| auto doesNotExistPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist"_s); |
| EXPECT_FALSE(FileSystem::fileType(doesNotExistPath)); |
| |
| EXPECT_EQ(FileSystem::fileType(tempFilePath()), FileSystem::FileType::Regular); |
| EXPECT_EQ(FileSystem::fileType(tempFileSymlinkPath()), FileSystem::FileType::SymbolicLink); |
| EXPECT_EQ(FileSystem::fileType(tempEmptyFolderSymlinkPath()), FileSystem::FileType::SymbolicLink); |
| EXPECT_EQ(FileSystem::fileType(tempEmptyFolderPath()), FileSystem::FileType::Directory); |
| |
| // Symlink to file symlink case. |
| auto symlinkToFileSymlinkPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "symlinkToSymlink"_s); |
| EXPECT_TRUE(FileSystem::createSymbolicLink(tempFileSymlinkPath(), symlinkToFileSymlinkPath)); |
| EXPECT_EQ(FileSystem::fileType(symlinkToFileSymlinkPath), FileSystem::FileType::SymbolicLink); |
| |
| // Symlink to directory symlink case. |
| FileSystem::PlatformFileHandle handle; |
| auto symlinkToDirectorySymlinkPath = FileSystem::openTemporaryFile("tempTestFile-symlink"_s, handle); |
| FileSystem::closeFile(handle); |
| FileSystem::deleteFile(symlinkToDirectorySymlinkPath); |
| EXPECT_TRUE(FileSystem::createSymbolicLink(tempEmptyFolderSymlinkPath(), symlinkToDirectorySymlinkPath)); |
| EXPECT_EQ(FileSystem::fileType(symlinkToDirectorySymlinkPath), FileSystem::FileType::SymbolicLink); |
| |
| // Broken file symlink case. |
| EXPECT_TRUE(FileSystem::deleteFile(tempFilePath())); |
| EXPECT_EQ(FileSystem::fileType(tempFileSymlinkPath()), FileSystem::FileType::SymbolicLink); |
| |
| // Broken directory symlink case. |
| EXPECT_TRUE(FileSystem::deleteNonEmptyDirectory(tempEmptyFolderPath())); |
| EXPECT_EQ(FileSystem::fileType(tempEmptyFolderSymlinkPath()), FileSystem::FileType::SymbolicLink); |
| } |
| |
| TEST_F(FileSystemTest, fileTypeFollowingSymlinks) |
| { |
| auto doesNotExistPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist"_s); |
| EXPECT_FALSE(FileSystem::fileTypeFollowingSymlinks(doesNotExistPath)); |
| |
| EXPECT_EQ(FileSystem::fileTypeFollowingSymlinks(tempFilePath()), FileSystem::FileType::Regular); |
| EXPECT_EQ(FileSystem::fileTypeFollowingSymlinks(tempFileSymlinkPath()), FileSystem::FileType::Regular); |
| EXPECT_EQ(FileSystem::fileTypeFollowingSymlinks(tempEmptyFolderSymlinkPath()), FileSystem::FileType::Directory); |
| EXPECT_EQ(FileSystem::fileTypeFollowingSymlinks(tempEmptyFolderPath()), FileSystem::FileType::Directory); |
| |
| // Symlink to file symlink case. |
| auto symlinkToFileSymlinkPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "symlinkToSymlink"_s); |
| EXPECT_TRUE(FileSystem::createSymbolicLink(tempFileSymlinkPath(), symlinkToFileSymlinkPath)); |
| EXPECT_EQ(FileSystem::fileTypeFollowingSymlinks(symlinkToFileSymlinkPath), FileSystem::FileType::Regular); |
| |
| // Symlink to directory symlink case. |
| FileSystem::PlatformFileHandle handle; |
| auto symlinkToDirectorySymlinkPath = FileSystem::openTemporaryFile("tempTestFile-symlink"_s, handle); |
| FileSystem::closeFile(handle); |
| FileSystem::deleteFile(symlinkToDirectorySymlinkPath); |
| EXPECT_TRUE(FileSystem::createSymbolicLink(tempEmptyFolderSymlinkPath(), symlinkToDirectorySymlinkPath)); |
| EXPECT_EQ(FileSystem::fileTypeFollowingSymlinks(symlinkToDirectorySymlinkPath), FileSystem::FileType::Directory); |
| |
| // Broken file symlink case. |
| EXPECT_TRUE(FileSystem::deleteFile(tempFilePath())); |
| EXPECT_FALSE(FileSystem::fileTypeFollowingSymlinks(tempFileSymlinkPath())); |
| |
| // Broken directory symlink case. |
| EXPECT_TRUE(FileSystem::deleteNonEmptyDirectory(tempEmptyFolderPath())); |
| EXPECT_FALSE(FileSystem::fileTypeFollowingSymlinks(tempEmptyFolderSymlinkPath())); |
| } |
| |
| #if OS(UNIX) |
| TEST_F(FileSystemTest, isHiddenFile) |
| { |
| auto hiddenFilePath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), ".hiddenFile"_s); |
| EXPECT_TRUE(FileSystem::isHiddenFile(hiddenFilePath)); |
| |
| EXPECT_FALSE(FileSystem::isHiddenFile(tempFilePath())); |
| } |
| #endif |
| |
| TEST_F(FileSystemTest, UnicodeDirectoryName) |
| { |
| String path = String::fromUTF8("/test/a\u0308lo/test.txt"); |
| String directoryName = FileSystem::parentPath(path); |
| String expectedDirectoryName = String::fromUTF8("/test/a\u0308lo"); |
| EXPECT_TRUE(expectedDirectoryName == directoryName); |
| } |
| |
| TEST_F(FileSystemTest, openExistingFileAndFailIfFileExists) |
| { |
| auto handle = FileSystem::openFile(tempFilePath(), FileSystem::FileOpenMode::ReadWrite, FileSystem::FileAccessPermission::All, true); |
| EXPECT_FALSE(FileSystem::isHandleValid(handle)); |
| } |
| |
| TEST_F(FileSystemTest, deleteNonEmptyDirectory) |
| { |
| FileSystem::PlatformFileHandle temporaryFile; |
| auto temporaryTestFolder = FileSystem::openTemporaryFile("deleteNonEmptyDirectoryTest"_s, temporaryFile); |
| FileSystem::closeFile(temporaryFile); |
| |
| EXPECT_TRUE(FileSystem::deleteFile(temporaryTestFolder)); |
| EXPECT_TRUE(FileSystem::makeAllDirectories(FileSystem::pathByAppendingComponents(temporaryTestFolder, { "subfolder"_s }))); |
| createTestFile(FileSystem::pathByAppendingComponent(temporaryTestFolder, "file1.txt"_s)); |
| createTestFile(FileSystem::pathByAppendingComponent(temporaryTestFolder, "file2.txt"_s)); |
| createTestFile(FileSystem::pathByAppendingComponents(temporaryTestFolder, { "subfolder"_s, "file3.txt"_s })); |
| createTestFile(FileSystem::pathByAppendingComponents(temporaryTestFolder, { "subfolder"_s, "file4.txt"_s })); |
| EXPECT_FALSE(FileSystem::deleteEmptyDirectory(temporaryTestFolder)); |
| EXPECT_TRUE(FileSystem::fileExists(temporaryTestFolder)); |
| EXPECT_TRUE(FileSystem::deleteNonEmptyDirectory(temporaryTestFolder)); |
| EXPECT_FALSE(FileSystem::fileExists(temporaryTestFolder)); |
| } |
| |
| TEST_F(FileSystemTest, fileExists) |
| { |
| EXPECT_TRUE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_TRUE(FileSystem::fileExists(tempFileSymlinkPath())); |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFilePath())); |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFolderPath())); |
| EXPECT_FALSE(FileSystem::fileExists(FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist"_s))); |
| } |
| |
| TEST_F(FileSystemTest, fileExistsBrokenSymlink) |
| { |
| auto doesNotExistPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist"_s); |
| auto symlinkPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist-symlink"_s); |
| EXPECT_TRUE(FileSystem::createSymbolicLink(doesNotExistPath, symlinkPath)); |
| EXPECT_FALSE(FileSystem::fileExists(doesNotExistPath)); |
| EXPECT_FALSE(FileSystem::fileExists(symlinkPath)); // fileExists() follows symlinks. |
| EXPECT_EQ(FileSystem::fileType(symlinkPath), FileSystem::FileType::SymbolicLink); |
| EXPECT_TRUE(FileSystem::deleteFile(symlinkPath)); |
| } |
| |
| TEST_F(FileSystemTest, fileExistsSymlinkToSymlink) |
| { |
| // Create a valid symlink to a symlink to a regular file. |
| auto symlinkPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "symlink"_s); |
| EXPECT_TRUE(FileSystem::createSymbolicLink(tempFileSymlinkPath(), symlinkPath)); |
| EXPECT_TRUE(FileSystem::fileExists(symlinkPath)); |
| EXPECT_EQ(FileSystem::fileType(symlinkPath), FileSystem::FileType::SymbolicLink); |
| EXPECT_EQ(FileSystem::fileTypeFollowingSymlinks(symlinkPath), FileSystem::FileType::Regular); |
| |
| // Break the symlink by deleting the target. |
| EXPECT_TRUE(FileSystem::deleteFile(tempFilePath())); |
| |
| EXPECT_FALSE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_FALSE(FileSystem::fileExists(tempFileSymlinkPath())); // fileExists() follows symlinks. |
| EXPECT_FALSE(FileSystem::fileExists(symlinkPath)); // fileExists() follows symlinks. |
| |
| EXPECT_EQ(FileSystem::fileType(symlinkPath), FileSystem::FileType::SymbolicLink); |
| EXPECT_EQ(FileSystem::fileType(tempFileSymlinkPath()), FileSystem::FileType::SymbolicLink); |
| |
| EXPECT_FALSE(FileSystem::fileTypeFollowingSymlinks(tempFileSymlinkPath())); |
| EXPECT_FALSE(FileSystem::fileTypeFollowingSymlinks(symlinkPath)); |
| |
| EXPECT_TRUE(FileSystem::deleteFile(symlinkPath)); |
| } |
| |
| TEST_F(FileSystemTest, deleteSymlink) |
| { |
| EXPECT_TRUE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_TRUE(FileSystem::fileExists(tempFileSymlinkPath())); |
| |
| EXPECT_TRUE(FileSystem::deleteFile(tempFileSymlinkPath())); |
| |
| // Should have deleted the symlink but not the target file. |
| EXPECT_TRUE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_FALSE(FileSystem::fileExists(tempFileSymlinkPath())); |
| } |
| |
| TEST_F(FileSystemTest, deleteFile) |
| { |
| EXPECT_TRUE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_TRUE(FileSystem::deleteFile(tempFilePath())); |
| EXPECT_FALSE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_FALSE(FileSystem::deleteFile(tempFilePath())); |
| } |
| |
| TEST_F(FileSystemTest, deleteFileOnEmptyDirectory) |
| { |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFolderPath())); |
| EXPECT_FALSE(FileSystem::deleteFile(tempEmptyFolderPath())); |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFolderPath())); |
| } |
| |
| TEST_F(FileSystemTest, deleteEmptyDirectory) |
| { |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFolderPath())); |
| EXPECT_TRUE(FileSystem::deleteEmptyDirectory(tempEmptyFolderPath())); |
| EXPECT_FALSE(FileSystem::fileExists(tempEmptyFolderPath())); |
| EXPECT_FALSE(FileSystem::deleteEmptyDirectory(tempEmptyFolderPath())); |
| } |
| |
| #if PLATFORM(MAC) |
| TEST_F(FileSystemTest, deleteEmptyDirectoryContainingDSStoreFile) |
| { |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFolderPath())); |
| |
| // Create .DSStore file. |
| auto dsStorePath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), ".DS_Store"_s); |
| auto dsStoreHandle = FileSystem::openFile(dsStorePath, FileSystem::FileOpenMode::Write); |
| FileSystem::writeToFile(dsStoreHandle, FileSystemTestData, strlen(FileSystemTestData)); |
| FileSystem::closeFile(dsStoreHandle); |
| EXPECT_TRUE(FileSystem::fileExists(dsStorePath)); |
| |
| EXPECT_TRUE(FileSystem::deleteEmptyDirectory(tempEmptyFolderPath())); |
| EXPECT_FALSE(FileSystem::fileExists(tempEmptyFolderPath())); |
| } |
| #endif |
| |
| TEST_F(FileSystemTest, deleteEmptyDirectoryOnNonEmptyDirectory) |
| { |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFolderPath())); |
| |
| // Create .DSStore file. |
| auto dsStorePath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), ".DS_Store"_s); |
| auto dsStoreHandle = FileSystem::openFile(dsStorePath, FileSystem::FileOpenMode::Write); |
| FileSystem::writeToFile(dsStoreHandle, FileSystemTestData, strlen(FileSystemTestData)); |
| FileSystem::closeFile(dsStoreHandle); |
| EXPECT_TRUE(FileSystem::fileExists(dsStorePath)); |
| |
| // Create a dummy file. |
| auto dummyFilePath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "dummyFile"_s); |
| auto dummyFileHandle = FileSystem::openFile(dummyFilePath, FileSystem::FileOpenMode::Write); |
| FileSystem::writeToFile(dummyFileHandle, FileSystemTestData, strlen(FileSystemTestData)); |
| FileSystem::closeFile(dummyFileHandle); |
| EXPECT_TRUE(FileSystem::fileExists(dummyFilePath)); |
| |
| EXPECT_FALSE(FileSystem::deleteEmptyDirectory(tempEmptyFolderPath())); |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFolderPath())); |
| EXPECT_TRUE(FileSystem::fileExists(dsStorePath)); |
| EXPECT_TRUE(FileSystem::fileExists(dummyFilePath)); |
| |
| EXPECT_TRUE(FileSystem::deleteNonEmptyDirectory(tempEmptyFolderPath())); |
| EXPECT_FALSE(FileSystem::fileExists(tempEmptyFolderPath())); |
| } |
| |
| TEST_F(FileSystemTest, deleteEmptyDirectoryOnARegularFile) |
| { |
| EXPECT_TRUE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_FALSE(FileSystem::deleteEmptyDirectory(tempFilePath())); |
| EXPECT_TRUE(FileSystem::fileExists(tempFilePath())); |
| } |
| |
| TEST_F(FileSystemTest, deleteEmptyDirectoryDoesNotExist) |
| { |
| auto doesNotExistPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist"_s); |
| EXPECT_FALSE(FileSystem::fileExists(doesNotExistPath)); |
| EXPECT_FALSE(FileSystem::deleteEmptyDirectory(doesNotExistPath)); |
| } |
| |
| TEST_F(FileSystemTest, moveFile) |
| { |
| auto destination = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "tempFile-moved"_s); |
| EXPECT_TRUE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_FALSE(FileSystem::fileExists(destination)); |
| EXPECT_TRUE(FileSystem::moveFile(tempFilePath(), destination)); |
| EXPECT_FALSE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_TRUE(FileSystem::fileExists(destination)); |
| EXPECT_FALSE(FileSystem::moveFile(tempFilePath(), destination)); |
| } |
| |
| TEST_F(FileSystemTest, moveFileOverwritesDestination) |
| { |
| EXPECT_TRUE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFilePath())); |
| |
| auto fileSize = FileSystem::fileSize(tempFilePath()); |
| ASSERT_TRUE(fileSize); |
| EXPECT_GT(*fileSize, 0U); |
| |
| fileSize = FileSystem::fileSize(tempEmptyFilePath()); |
| ASSERT_TRUE(fileSize); |
| EXPECT_EQ(*fileSize, 0U); |
| |
| EXPECT_TRUE(FileSystem::moveFile(tempFilePath(), tempEmptyFilePath())); |
| EXPECT_FALSE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFilePath())); |
| |
| fileSize = FileSystem::fileSize(tempEmptyFilePath()); |
| ASSERT_TRUE(fileSize); |
| EXPECT_GT(*fileSize, 0U); |
| } |
| |
| TEST_F(FileSystemTest, moveDirectory) |
| { |
| FileSystem::PlatformFileHandle temporaryFile; |
| auto temporaryTestFolder = FileSystem::openTemporaryFile("moveDirectoryTest"_s, temporaryFile); |
| FileSystem::closeFile(temporaryFile); |
| |
| EXPECT_TRUE(FileSystem::deleteFile(temporaryTestFolder)); |
| EXPECT_TRUE(FileSystem::makeAllDirectories(temporaryTestFolder)); |
| auto testFilePath = FileSystem::pathByAppendingComponent(temporaryTestFolder, "testFile"_s); |
| auto fileHandle = FileSystem::openFile(testFilePath, FileSystem::FileOpenMode::Write); |
| FileSystem::writeToFile(fileHandle, FileSystemTestData, strlen(FileSystemTestData)); |
| FileSystem::closeFile(fileHandle); |
| |
| EXPECT_TRUE(FileSystem::fileExists(testFilePath)); |
| |
| auto destinationPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "moveDirectoryTest"_s); |
| EXPECT_TRUE(FileSystem::moveFile(temporaryTestFolder, destinationPath)); |
| EXPECT_FALSE(FileSystem::fileExists(temporaryTestFolder)); |
| EXPECT_FALSE(FileSystem::fileExists(testFilePath)); |
| EXPECT_TRUE(FileSystem::fileExists(destinationPath)); |
| EXPECT_TRUE(FileSystem::fileExists(FileSystem::pathByAppendingComponent(destinationPath, "testFile"_s))); |
| |
| EXPECT_FALSE(FileSystem::deleteEmptyDirectory(destinationPath)); |
| EXPECT_TRUE(FileSystem::fileExists(destinationPath)); |
| } |
| |
| TEST_F(FileSystemTest, fileSize) |
| { |
| EXPECT_TRUE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFilePath())); |
| |
| auto fileSize = FileSystem::fileSize(tempFilePath()); |
| ASSERT_TRUE(fileSize); |
| EXPECT_GT(*fileSize, 0U); |
| |
| fileSize = FileSystem::fileSize(tempEmptyFilePath()); |
| ASSERT_TRUE(fileSize); |
| EXPECT_EQ(*fileSize, 0U); |
| |
| String fileThatDoesNotExist = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist"_s); |
| fileSize = FileSystem::fileSize(fileThatDoesNotExist); |
| EXPECT_TRUE(!fileSize); |
| } |
| |
| TEST_F(FileSystemTest, makeAllDirectories) |
| { |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFolderPath())); |
| EXPECT_EQ(FileSystem::fileType(tempEmptyFolderPath()), FileSystem::FileType::Directory); |
| EXPECT_TRUE(FileSystem::makeAllDirectories(tempEmptyFolderPath())); |
| String subFolderPath = FileSystem::pathByAppendingComponents(tempEmptyFolderPath(), { "subFolder1"_s, "subFolder2"_s, "subFolder3"_s }); |
| EXPECT_FALSE(FileSystem::fileExists(subFolderPath)); |
| EXPECT_TRUE(FileSystem::makeAllDirectories(subFolderPath)); |
| EXPECT_TRUE(FileSystem::fileExists(subFolderPath)); |
| EXPECT_EQ(FileSystem::fileType(subFolderPath), FileSystem::FileType::Directory); |
| EXPECT_TRUE(FileSystem::deleteNonEmptyDirectory(tempEmptyFolderPath())); |
| EXPECT_FALSE(FileSystem::fileExists(subFolderPath)); |
| String invalidFolderPath = makeString('\0', 'a'); |
| EXPECT_FALSE(FileSystem::makeAllDirectories(invalidFolderPath)); |
| EXPECT_FALSE(FileSystem::makeAllDirectories(emptyString())); |
| } |
| |
| TEST_F(FileSystemTest, volumeFreeSpace) |
| { |
| auto freeSpace = FileSystem::volumeFreeSpace(tempFilePath()); |
| ASSERT_TRUE(freeSpace); |
| EXPECT_GT(*freeSpace, 0U); |
| |
| String fileThatDoesNotExist = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist"_s); |
| EXPECT_FALSE(FileSystem::volumeFreeSpace(fileThatDoesNotExist)); |
| } |
| |
| TEST_F(FileSystemTest, createSymbolicLink) |
| { |
| auto symlinkPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "tempFile-symlink"_s); |
| EXPECT_FALSE(FileSystem::fileExists(symlinkPath)); |
| EXPECT_TRUE(FileSystem::createSymbolicLink(tempFilePath(), symlinkPath)); |
| EXPECT_TRUE(FileSystem::fileExists(symlinkPath)); |
| |
| EXPECT_EQ(FileSystem::fileType(symlinkPath), FileSystem::FileType::SymbolicLink); |
| |
| EXPECT_TRUE(FileSystem::deleteFile(symlinkPath)); |
| EXPECT_FALSE(FileSystem::fileExists(symlinkPath)); |
| EXPECT_TRUE(FileSystem::fileExists(tempFilePath())); |
| } |
| |
| TEST_F(FileSystemTest, createSymbolicLinkFolder) |
| { |
| auto symlinkPath = tempEmptyFolderSymlinkPath(); |
| EXPECT_TRUE(FileSystem::deleteFile(symlinkPath)); |
| EXPECT_FALSE(FileSystem::fileExists(symlinkPath)); |
| EXPECT_TRUE(FileSystem::createSymbolicLink(tempEmptyFolderPath(), symlinkPath)); |
| EXPECT_TRUE(FileSystem::fileExists(symlinkPath)); |
| |
| EXPECT_EQ(FileSystem::fileType(symlinkPath), FileSystem::FileType::SymbolicLink); |
| |
| EXPECT_TRUE(FileSystem::deleteFile(symlinkPath)); |
| EXPECT_FALSE(FileSystem::fileExists(symlinkPath)); |
| EXPECT_TRUE(FileSystem::fileExists(tempEmptyFolderPath())); |
| } |
| |
| TEST_F(FileSystemTest, createSymbolicLinkFileDoesNotExist) |
| { |
| String fileThatDoesNotExist = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist"_s); |
| EXPECT_FALSE(FileSystem::fileExists(fileThatDoesNotExist)); |
| |
| auto symlinkPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist-symlink"_s); |
| EXPECT_FALSE(FileSystem::fileExists(symlinkPath)); |
| EXPECT_TRUE(FileSystem::createSymbolicLink(fileThatDoesNotExist, symlinkPath)); |
| EXPECT_FALSE(FileSystem::fileExists(symlinkPath)); |
| } |
| |
| TEST_F(FileSystemTest, createHardLink) |
| { |
| auto hardlinkPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "tempFile-hardlink"_s); |
| EXPECT_FALSE(FileSystem::fileExists(hardlinkPath)); |
| |
| auto fileSize = FileSystem::fileSize(tempFilePath()); |
| ASSERT_TRUE(fileSize); |
| EXPECT_GT(*fileSize, 0U); |
| |
| EXPECT_TRUE(FileSystem::hardLink(tempFilePath(), hardlinkPath)); |
| |
| EXPECT_TRUE(FileSystem::fileExists(hardlinkPath)); |
| |
| auto linkFileSize = FileSystem::fileSize(hardlinkPath); |
| ASSERT_TRUE(linkFileSize); |
| EXPECT_EQ(*linkFileSize, *fileSize); |
| |
| EXPECT_EQ(FileSystem::fileType(hardlinkPath), FileSystem::FileType::Regular); |
| |
| EXPECT_TRUE(FileSystem::deleteFile(tempFilePath())); |
| EXPECT_FALSE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_TRUE(FileSystem::fileExists(hardlinkPath)); |
| |
| linkFileSize = FileSystem::fileSize(hardlinkPath); |
| ASSERT_TRUE(linkFileSize); |
| EXPECT_EQ(*linkFileSize, *fileSize); |
| } |
| |
| TEST_F(FileSystemTest, createHardLinkOrCopyFile) |
| { |
| auto hardlinkPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "tempFile-hardlink"_s); |
| EXPECT_FALSE(FileSystem::fileExists(hardlinkPath)); |
| |
| auto fileSize = FileSystem::fileSize(tempFilePath()); |
| ASSERT_TRUE(fileSize); |
| EXPECT_GT(*fileSize, 0U); |
| |
| EXPECT_TRUE(FileSystem::hardLinkOrCopyFile(tempFilePath(), hardlinkPath)); |
| |
| EXPECT_TRUE(FileSystem::fileExists(hardlinkPath)); |
| |
| auto linkFileSize = FileSystem::fileSize(hardlinkPath); |
| ASSERT_TRUE(linkFileSize); |
| EXPECT_EQ(*linkFileSize, *fileSize); |
| |
| EXPECT_EQ(FileSystem::fileType(hardlinkPath), FileSystem::FileType::Regular); |
| |
| EXPECT_TRUE(FileSystem::deleteFile(tempFilePath())); |
| EXPECT_FALSE(FileSystem::fileExists(tempFilePath())); |
| EXPECT_TRUE(FileSystem::fileExists(hardlinkPath)); |
| |
| linkFileSize = FileSystem::fileSize(hardlinkPath); |
| ASSERT_TRUE(linkFileSize); |
| EXPECT_EQ(*linkFileSize, *fileSize); |
| } |
| |
| TEST_F(FileSystemTest, hardLinkCount) |
| { |
| auto linkCount = FileSystem::hardLinkCount(tempFilePath()); |
| ASSERT_TRUE(!!linkCount); |
| EXPECT_EQ(*linkCount, 1U); |
| |
| auto hardlink1Path = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "tempFile-hardlink1"_s); |
| EXPECT_TRUE(FileSystem::hardLink(tempFilePath(), hardlink1Path)); |
| linkCount = FileSystem::hardLinkCount(tempFilePath()); |
| ASSERT_TRUE(!!linkCount); |
| EXPECT_EQ(*linkCount, 2U); |
| |
| auto hardlink2Path = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "tempFile-hardlink2"_s); |
| EXPECT_TRUE(FileSystem::hardLink(tempFilePath(), hardlink2Path)); |
| linkCount = FileSystem::hardLinkCount(tempFilePath()); |
| ASSERT_TRUE(!!linkCount); |
| EXPECT_EQ(*linkCount, 3U); |
| |
| EXPECT_TRUE(FileSystem::deleteFile(hardlink1Path)); |
| linkCount = FileSystem::hardLinkCount(tempFilePath()); |
| ASSERT_TRUE(!!linkCount); |
| EXPECT_EQ(*linkCount, 2U); |
| |
| EXPECT_TRUE(FileSystem::deleteFile(hardlink2Path)); |
| linkCount = FileSystem::hardLinkCount(tempFilePath()); |
| ASSERT_TRUE(!!linkCount); |
| EXPECT_EQ(*linkCount, 1U); |
| |
| EXPECT_TRUE(FileSystem::deleteFile(tempFilePath())); |
| linkCount = FileSystem::hardLinkCount(tempFilePath()); |
| EXPECT_TRUE(!linkCount); |
| } |
| |
| static void runGetFileModificationTimeTest(const String& path, Function<std::optional<WallTime>(const String&)>&& fileModificationTime) |
| { |
| auto modificationTime = fileModificationTime(path); |
| EXPECT_TRUE(!!modificationTime); |
| if (!modificationTime) |
| return; |
| |
| unsigned timeout = 0; |
| while (*modificationTime >= WallTime::now() && ++timeout < 20) |
| TestWebKitAPI::Util::sleep(0.1); |
| EXPECT_LT(modificationTime->secondsSinceEpoch().value(), WallTime::now().secondsSinceEpoch().value()); |
| |
| auto timeBeforeModification = WallTime::now(); |
| |
| TestWebKitAPI::Util::sleep(2); |
| |
| // Modify the file. |
| auto fileHandle = FileSystem::openFile(path, FileSystem::FileOpenMode::ReadWrite); |
| EXPECT_TRUE(FileSystem::isHandleValid(fileHandle)); |
| FileSystem::writeToFile(fileHandle, "foo", strlen("foo")); |
| FileSystem::closeFile(fileHandle); |
| |
| auto newModificationTime = fileModificationTime(path); |
| EXPECT_TRUE(!!newModificationTime); |
| if (!newModificationTime) |
| return; |
| |
| EXPECT_GT(newModificationTime->secondsSinceEpoch().value(), modificationTime->secondsSinceEpoch().value()); |
| EXPECT_GT(newModificationTime->secondsSinceEpoch().value(), timeBeforeModification.secondsSinceEpoch().value()); |
| } |
| |
| TEST_F(FileSystemTest, fileModificationTime) |
| { |
| runGetFileModificationTimeTest(tempFilePath(), [](const String& path) { |
| return FileSystem::fileModificationTime(path); |
| }); |
| } |
| |
| TEST_F(FileSystemTest, updateFileModificationTime) |
| { |
| auto modificationTime = FileSystem::fileModificationTime(tempFilePath()); |
| ASSERT_TRUE(!!modificationTime); |
| |
| unsigned timeout = 0; |
| while (*modificationTime >= WallTime::now() && ++timeout < 20) |
| TestWebKitAPI::Util::sleep(0.1); |
| EXPECT_LT(modificationTime->secondsSinceEpoch().value(), WallTime::now().secondsSinceEpoch().value()); |
| |
| TestWebKitAPI::Util::sleep(1); |
| |
| EXPECT_TRUE(FileSystem::updateFileModificationTime(tempFilePath())); |
| auto newModificationTime = FileSystem::fileModificationTime(tempFilePath()); |
| ASSERT_TRUE(!!newModificationTime); |
| EXPECT_GT(newModificationTime->secondsSinceEpoch().value(), modificationTime->secondsSinceEpoch().value()); |
| |
| auto doesNotExistPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist"_s); |
| EXPECT_FALSE(FileSystem::updateFileModificationTime(doesNotExistPath)); |
| } |
| |
| TEST_F(FileSystemTest, pathFileName) |
| { |
| auto testPath = FileSystem::pathByAppendingComponents(tempEmptyFolderPath(), { "subfolder"_s, "filename.txt"_s }); |
| EXPECT_STREQ("filename.txt", FileSystem::pathFileName(testPath).utf8().data()); |
| |
| #if OS(UNIX) |
| EXPECT_STREQ(".", FileSystem::pathFileName("."_s).utf8().data()); |
| EXPECT_STREQ("..", FileSystem::pathFileName(".."_s).utf8().data()); |
| EXPECT_STREQ("", FileSystem::pathFileName("/"_s).utf8().data()); |
| EXPECT_STREQ(".", FileSystem::pathFileName("/foo/."_s).utf8().data()); |
| EXPECT_STREQ("..", FileSystem::pathFileName("/foo/.."_s).utf8().data()); |
| EXPECT_STREQ("", FileSystem::pathFileName("/foo/"_s).utf8().data()); |
| EXPECT_STREQ("host", FileSystem::pathFileName("//host"_s).utf8().data()); |
| #endif |
| #if OS(WINDOWS) |
| EXPECT_STREQ("", FileSystem::pathFileName("C:\\"_s).utf8().data()); |
| EXPECT_STREQ("foo", FileSystem::pathFileName("C:\\foo"_s).utf8().data()); |
| EXPECT_STREQ("", FileSystem::pathFileName("C:\\foo\\"_s).utf8().data()); |
| EXPECT_STREQ("bar.txt", FileSystem::pathFileName("C:\\foo\\bar.txt"_s).utf8().data()); |
| #endif |
| } |
| |
| TEST_F(FileSystemTest, parentPath) |
| { |
| auto testPath = FileSystem::pathByAppendingComponents(tempEmptyFolderPath(), { "subfolder"_s, "filename.txt"_s }); |
| EXPECT_STREQ(FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "subfolder"_s).utf8().data(), FileSystem::parentPath(testPath).utf8().data()); |
| #if OS(UNIX) |
| EXPECT_STREQ("/var/tmp", FileSystem::parentPath("/var/tmp/example.txt"_s).utf8().data()); |
| EXPECT_STREQ("/var/tmp", FileSystem::parentPath("/var/tmp/"_s).utf8().data()); |
| EXPECT_STREQ("/var/tmp", FileSystem::parentPath("/var/tmp/."_s).utf8().data()); |
| EXPECT_STREQ("/", FileSystem::parentPath("/"_s).utf8().data()); |
| #endif |
| #if OS(WINDOWS) |
| EXPECT_STREQ("C:\\foo", FileSystem::parentPath("C:\\foo\\example.txt"_s).utf8().data()); |
| EXPECT_STREQ("C:\\", FileSystem::parentPath("C:\\"_s).utf8().data()); |
| #endif |
| } |
| |
| TEST_F(FileSystemTest, pathByAppendingComponent) |
| { |
| #if OS(UNIX) |
| EXPECT_STREQ("/var", FileSystem::pathByAppendingComponent("/"_s, "var"_s).utf8().data()); |
| EXPECT_STREQ("/var/tmp", FileSystem::pathByAppendingComponent("/var/"_s, "tmp"_s).utf8().data()); |
| EXPECT_STREQ("/var/tmp", FileSystem::pathByAppendingComponent("/var"_s, "tmp"_s).utf8().data()); |
| EXPECT_STREQ("/var/tmp/file.txt", FileSystem::pathByAppendingComponent("/var/tmp"_s, "file.txt"_s).utf8().data()); |
| EXPECT_STREQ("/var/", FileSystem::pathByAppendingComponent("/var"_s, ""_s).utf8().data()); |
| EXPECT_STREQ("/var/", FileSystem::pathByAppendingComponent("/var/"_s, ""_s).utf8().data()); |
| #endif |
| #if OS(WINDOWS) |
| EXPECT_STREQ("C:\\Foo", FileSystem::pathByAppendingComponent("C:\\"_s, "Foo"_s).utf8().data()); |
| EXPECT_STREQ("C:\\Foo\\Bar", FileSystem::pathByAppendingComponent("C:\\Foo"_s, "Bar"_s).utf8().data()); |
| EXPECT_STREQ("C:\\Foo\\Bar\\File.txt", FileSystem::pathByAppendingComponent("C:\\Foo\\Bar"_s, "File.txt"_s).utf8().data()); |
| #endif |
| } |
| |
| TEST_F(FileSystemTest, pathByAppendingComponents) |
| { |
| EXPECT_STREQ(tempEmptyFolderPath().utf8().data(), FileSystem::pathByAppendingComponents(tempEmptyFolderPath(), { }).utf8().data()); |
| EXPECT_STREQ(FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "file.txt"_s).utf8().data(), FileSystem::pathByAppendingComponents(tempEmptyFolderPath(), { "file.txt"_s }).utf8().data()); |
| #if OS(UNIX) |
| EXPECT_STREQ("/var/tmp/file.txt", FileSystem::pathByAppendingComponents("/"_s, { "var"_s, "tmp"_s, "file.txt"_s }).utf8().data()); |
| EXPECT_STREQ("/var/tmp/file.txt", FileSystem::pathByAppendingComponents("/var"_s, { "tmp"_s, "file.txt"_s }).utf8().data()); |
| EXPECT_STREQ("/var/tmp/file.txt", FileSystem::pathByAppendingComponents("/var/"_s, { "tmp"_s, "file.txt"_s }).utf8().data()); |
| EXPECT_STREQ("/var/tmp/file.txt", FileSystem::pathByAppendingComponents("/var/tmp"_s, { "file.txt"_s }).utf8().data()); |
| #endif |
| #if OS(WINDOWS) |
| EXPECT_STREQ("C:\\Foo\\Bar\\File.txt", FileSystem::pathByAppendingComponents("C:\\"_s, { "Foo"_s, "Bar"_s, "File.txt"_s }).utf8().data()); |
| EXPECT_STREQ("C:\\Foo\\Bar\\File.txt", FileSystem::pathByAppendingComponents("C:\\Foo"_s, { "Bar"_s, "File.txt"_s }).utf8().data()); |
| EXPECT_STREQ("C:\\Foo\\Bar\\File.txt", FileSystem::pathByAppendingComponents("C:\\Foo\\"_s, { "Bar"_s, "File.txt"_s }).utf8().data()); |
| EXPECT_STREQ("C:\\Foo\\Bar\\File.txt", FileSystem::pathByAppendingComponents("C:\\Foo\\Bar"_s, { "File.txt"_s }).utf8().data()); |
| EXPECT_STREQ("C:\\Foo\\Bar\\File.txt", FileSystem::pathByAppendingComponents("C:\\Foo\\Bar\\"_s, { "File.txt"_s }).utf8().data()); |
| #endif |
| } |
| |
| TEST_F(FileSystemTest, listDirectory) |
| { |
| createTestFile(FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "a.txt"_s)); |
| createTestFile(FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "b.txt"_s)); |
| createTestFile(FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "bar.png"_s)); |
| createTestFile(FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "foo.png"_s)); |
| FileSystem::makeAllDirectories(FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "subfolder"_s)); |
| createTestFile(FileSystem::pathByAppendingComponents(tempEmptyFolderPath(), { "subfolder"_s, "c.txt"_s })); |
| createTestFile(FileSystem::pathByAppendingComponents(tempEmptyFolderPath(), { "subfolder"_s, "d.txt"_s })); |
| |
| auto matches = FileSystem::listDirectory(tempEmptyFolderPath()); |
| ASSERT_EQ(matches.size(), 5U); |
| std::sort(matches.begin(), matches.end(), WTF::codePointCompareLessThan); |
| EXPECT_STREQ(matches[0].utf8().data(), "a.txt"); |
| EXPECT_STREQ(matches[1].utf8().data(), "b.txt"); |
| EXPECT_STREQ(matches[2].utf8().data(), "bar.png"); |
| EXPECT_STREQ(matches[3].utf8().data(), "foo.png"); |
| EXPECT_STREQ(matches[4].utf8().data(), "subfolder"); |
| |
| matches = FileSystem::listDirectory(FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "subfolder"_s)); |
| ASSERT_EQ(matches.size(), 2U); |
| std::sort(matches.begin(), matches.end(), WTF::codePointCompareLessThan); |
| EXPECT_STREQ(matches[0].utf8().data(), "c.txt"); |
| EXPECT_STREQ(matches[1].utf8().data(), "d.txt"); |
| |
| matches = FileSystem::listDirectory(FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist"_s)); |
| ASSERT_EQ(matches.size(), 0U); |
| |
| matches = FileSystem::listDirectory(FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "a.txt"_s)); |
| ASSERT_EQ(matches.size(), 0U); |
| |
| EXPECT_TRUE(FileSystem::deleteNonEmptyDirectory(tempEmptyFolderPath())); |
| } |
| |
| TEST_F(FileSystemTest, realPath) |
| { |
| auto doesNotExistPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist"_s); |
| EXPECT_STREQ(FileSystem::realPath(doesNotExistPath).utf8().data(), doesNotExistPath.utf8().data()); |
| |
| auto resolvedTempFilePath = FileSystem::realPath(tempFilePath()); |
| EXPECT_STREQ(FileSystem::realPath(resolvedTempFilePath).utf8().data(), resolvedTempFilePath.utf8().data()); |
| EXPECT_STREQ(FileSystem::realPath(tempFileSymlinkPath()).utf8().data(), resolvedTempFilePath.utf8().data()); // Should resolve file symlink. |
| |
| auto resolvedTempEmptyFolderPath = FileSystem::realPath(tempEmptyFolderPath()); |
| EXPECT_STREQ(FileSystem::realPath(resolvedTempEmptyFolderPath).utf8().data(), resolvedTempEmptyFolderPath.utf8().data()); |
| EXPECT_STREQ(FileSystem::realPath(tempEmptyFolderSymlinkPath()).utf8().data(), resolvedTempEmptyFolderPath.utf8().data()); // Should resolve directory symlink. |
| |
| // Symlink to symlink case. |
| auto symlinkToSymlinkPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "symlinkToSymlink"_s); |
| EXPECT_TRUE(FileSystem::createSymbolicLink(tempFileSymlinkPath(), symlinkToSymlinkPath)); |
| EXPECT_STREQ(FileSystem::realPath(symlinkToSymlinkPath).utf8().data(), resolvedTempFilePath.utf8().data()); // Should resolve all symlinks. |
| |
| auto subFolderPath = FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "subfolder"_s); |
| FileSystem::makeAllDirectories(subFolderPath); |
| auto resolvedSubFolderPath = FileSystem::realPath(subFolderPath); |
| EXPECT_STREQ(FileSystem::realPath(FileSystem::pathByAppendingComponent(subFolderPath, ".."_s)).utf8().data(), resolvedTempEmptyFolderPath.utf8().data()); // Should resolve "..". |
| EXPECT_STREQ(FileSystem::realPath(FileSystem::pathByAppendingComponents(subFolderPath, { ".."_s, "subfolder"_s })).utf8().data(), resolvedSubFolderPath.utf8().data()); // Should resolve "..". |
| EXPECT_STREQ(FileSystem::realPath(FileSystem::pathByAppendingComponents(subFolderPath, { ".."_s, "."_s, "."_s, "subfolder"_s })).utf8().data(), resolvedSubFolderPath.utf8().data()); // Should resolve ".." and "." |
| } |
| |
| TEST_F(FileSystemTest, readEntireFile) |
| { |
| EXPECT_FALSE(FileSystem::readEntireFile(FileSystem::invalidPlatformFileHandle)); |
| EXPECT_FALSE(FileSystem::readEntireFile(emptyString())); |
| EXPECT_FALSE(FileSystem::readEntireFile(FileSystem::pathByAppendingComponent(tempEmptyFolderPath(), "does-not-exist"_s))); |
| EXPECT_FALSE(FileSystem::readEntireFile(tempEmptyFilePath())); |
| |
| auto buffer = FileSystem::readEntireFile(tempFilePath()); |
| EXPECT_TRUE(buffer); |
| auto contents = String::adopt(WTFMove(buffer.value())); |
| EXPECT_STREQ(contents.utf8().data(), FileSystemTestData); |
| } |
| |
| TEST_F(FileSystemTest, makeSafeToUseMemoryMapForPath) |
| { |
| EXPECT_TRUE(FileSystem::makeSafeToUseMemoryMapForPath(tempFilePath())); |
| auto result = FileSystem::makeSafeToUseMemoryMapForPath("Thisisnotarealfile"_str); |
| #if PLATFORM(IOS_FAMILY) && !PLATFORM(IOS_FAMILY_SIMULATOR) |
| // NSFileProtectionKey only actually means anything on-device. |
| EXPECT_FALSE(result); |
| #else |
| EXPECT_TRUE(result); |
| #endif |
| } |
| |
| } // namespace TestWebKitAPI |