blob: 31c94aadf5338aa60b8155a123bacdb63838e2c3 [file] [log] [blame]
//===- unittests/Basic/FileSystemTest.cpp ---------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "../BuildSystem/TempDir.h"
#include "llbuild/Basic/FileSystem.h"
#include "llbuild/Basic/LLVM.h"
#include "llbuild/Basic/PlatformUtility.h"
#include "llbuild/Basic/Stat.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
using namespace llbuild;
using namespace llbuild::basic;
namespace {
TEST(FileSystemTest, basic) {
// Check basic sanity of the local filesystem object.
auto fs = createLocalFileSystem();
// Write a temp file.
SmallString<256> tempPath;
llvm::sys::fs::createTemporaryFile("FileSystemTests", "txt", tempPath);
{
std::error_code ec;
llvm::raw_fd_ostream os(tempPath.str(), ec, llvm::sys::fs::F_Text);
EXPECT_FALSE(ec);
os << "Hello, world!\n";
os.close();
}
auto missingFileInfo = fs->getFileInfo("/does/not/exists");
EXPECT_TRUE(missingFileInfo.isMissing());
auto ourFileInfo = fs->getFileInfo(tempPath.str());
EXPECT_FALSE(ourFileInfo.isMissing());
auto missingFileContents = fs->getFileContents("/does/not/exist");
EXPECT_EQ(missingFileContents.get(), nullptr);
auto ourFileContents = fs->getFileContents(tempPath.str());
EXPECT_EQ(ourFileContents->getBuffer().str(), "Hello, world!\n");
// Remote the temporary file.
auto ec = llvm::sys::fs::remove(tempPath.str());
EXPECT_FALSE(ec);
}
TEST(FileSystemTest, testRecursiveRemoval) {
TmpDir rootTempDir{ __FUNCTION__ };
SmallString<256> tempDir { rootTempDir.str() };
llvm::sys::path::append(tempDir, "root");
sys::mkdir(tempDir.c_str());
SmallString<256> file{ tempDir.str() };
llvm::sys::path::append(file, "test.txt");
{
std::error_code ec;
llvm::raw_fd_ostream os(file.str(), ec, llvm::sys::fs::F_Text);
EXPECT_FALSE(ec);
os << "Hello, world!\n";
os.close();
}
SmallString<256> dir{ tempDir.str() };
llvm::sys::path::append(dir, "subdir");
sys::mkdir(dir.c_str());
llvm::sys::path::append(dir, "file_in_subdir.txt");
{
std::error_code ec;
llvm::raw_fd_ostream os(dir.str(), ec, llvm::sys::fs::F_Text);
EXPECT_FALSE(ec);
os << "Hello, world!\n";
os.close();
}
auto fs = createLocalFileSystem();
bool result = fs->remove(tempDir.c_str());
EXPECT_TRUE(result);
sys::StatStruct statbuf;
EXPECT_EQ(-1, sys::stat(tempDir.c_str(), &statbuf));
EXPECT_EQ(ENOENT, errno);
}
TEST(FileSystemTest, testRecursiveRemovalDoesNotFollowSymlinks) {
TmpDir rootTempDir{ __FUNCTION__ };
SmallString<256> file{ rootTempDir.str() };
llvm::sys::path::append(file, "test.txt");
{
std::error_code ec;
llvm::raw_fd_ostream os(file.str(), ec, llvm::sys::fs::F_Text);
EXPECT_FALSE(ec);
os << "Hello, world!\n";
os.close();
}
SmallString<256> otherDir{ rootTempDir.str() };
llvm::sys::path::append(otherDir, "other_dir");
sys::mkdir(otherDir.c_str());
SmallString<256> otherFile{ otherDir.str() };
llvm::sys::path::append(otherFile, "test.txt");
{
std::error_code ec;
llvm::raw_fd_ostream os(otherFile.str(), ec, llvm::sys::fs::F_Text);
EXPECT_FALSE(ec);
os << "Hello, world!\n";
os.close();
}
SmallString<256> tempDir { rootTempDir.str() };
llvm::sys::path::append(tempDir, "root");
sys::mkdir(tempDir.c_str());
SmallString<256> linkPath { tempDir.str() };
llvm::sys::path::append(linkPath, "link.txt");
int res = sys::symlink(file.c_str(), linkPath.c_str());
EXPECT_EQ(res, 0);
SmallString<256> directoryLinkPath { tempDir.str() };
llvm::sys::path::append(directoryLinkPath, "link_to_other_dir");
res = sys::symlink(otherDir.c_str(), directoryLinkPath.c_str());
EXPECT_EQ(res, 0);
auto fs = createLocalFileSystem();
bool result = fs->remove(tempDir.c_str());
EXPECT_TRUE(result);
sys::StatStruct statbuf;
EXPECT_EQ(-1, sys::stat(tempDir.c_str(), &statbuf));
EXPECT_EQ(ENOENT, errno);
// Verify that the symlink target still exists.
EXPECT_EQ(0, sys::stat(file.c_str(), &statbuf));
// Verify that we did not delete the symlinked directories contents.
EXPECT_EQ(0, sys::stat(otherFile.c_str(), &statbuf));
}
}