xref: /llvm-project/lldb/unittests/Host/FileSystemTest.cpp (revision 5232cec8f947ed8bff4ca57f990954228d58e66d)
180814287SRaphael Isemann //===-- FileSystemTest.cpp ------------------------------------------------===//
21408bf72SPavel Labath //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61408bf72SPavel Labath //
71408bf72SPavel Labath //===----------------------------------------------------------------------===//
81408bf72SPavel Labath 
946376966SJonas Devlieghere #include "gmock/gmock.h"
101408bf72SPavel Labath #include "gtest/gtest.h"
111408bf72SPavel Labath 
121408bf72SPavel Labath #include "lldb/Host/FileSystem.h"
1346376966SJonas Devlieghere #include "llvm/Support/Errc.h"
141408bf72SPavel Labath 
151408bf72SPavel Labath extern const char *TestMainArgv0;
161408bf72SPavel Labath 
171408bf72SPavel Labath using namespace lldb_private;
1846376966SJonas Devlieghere using namespace llvm;
1946376966SJonas Devlieghere using llvm::sys::fs::UniqueID;
2046376966SJonas Devlieghere 
2146376966SJonas Devlieghere // Modified from llvm/unittests/Support/VirtualFileSystemTest.cpp
2246376966SJonas Devlieghere namespace {
2346376966SJonas Devlieghere struct DummyFile : public vfs::File {
2446376966SJonas Devlieghere   vfs::Status S;
DummyFile__anonab014d540111::DummyFile2546376966SJonas Devlieghere   explicit DummyFile(vfs::Status S) : S(S) {}
status__anonab014d540111::DummyFile2646376966SJonas Devlieghere   llvm::ErrorOr<vfs::Status> status() override { return S; }
2746376966SJonas Devlieghere   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBuffer__anonab014d540111::DummyFile2846376966SJonas Devlieghere   getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator,
2946376966SJonas Devlieghere             bool IsVolatile) override {
3046376966SJonas Devlieghere     llvm_unreachable("unimplemented");
3146376966SJonas Devlieghere   }
close__anonab014d540111::DummyFile3246376966SJonas Devlieghere   std::error_code close() override { return std::error_code(); }
3346376966SJonas Devlieghere };
3446376966SJonas Devlieghere 
3546376966SJonas Devlieghere class DummyFileSystem : public vfs::FileSystem {
3646376966SJonas Devlieghere   int FSID;   // used to produce UniqueIDs
3728c878aeSShafik Yaghmour   int FileID = 0; // used to produce UniqueIDs
3846376966SJonas Devlieghere   std::string cwd;
3946376966SJonas Devlieghere   std::map<std::string, vfs::Status> FilesAndDirs;
4046376966SJonas Devlieghere 
getNextFSID()4146376966SJonas Devlieghere   static int getNextFSID() {
4246376966SJonas Devlieghere     static int Count = 0;
4346376966SJonas Devlieghere     return Count++;
4446376966SJonas Devlieghere   }
4546376966SJonas Devlieghere 
4646376966SJonas Devlieghere public:
DummyFileSystem()4728c878aeSShafik Yaghmour   DummyFileSystem() : FSID(getNextFSID()) {}
4846376966SJonas Devlieghere 
status(const Twine & Path)4946376966SJonas Devlieghere   ErrorOr<vfs::Status> status(const Twine &Path) override {
5046376966SJonas Devlieghere     std::map<std::string, vfs::Status>::iterator I =
5146376966SJonas Devlieghere         FilesAndDirs.find(Path.str());
5246376966SJonas Devlieghere     if (I == FilesAndDirs.end())
5346376966SJonas Devlieghere       return make_error_code(llvm::errc::no_such_file_or_directory);
542c1108f4SJason Molenda     // Simulate a broken symlink, where it points to a file/dir that
552c1108f4SJason Molenda     // does not exist.
562c1108f4SJason Molenda     if (I->second.isSymlink() &&
572c1108f4SJason Molenda         I->second.getPermissions() == sys::fs::perms::no_perms)
582c1108f4SJason Molenda       return std::error_code(ENOENT, std::generic_category());
5946376966SJonas Devlieghere     return I->second;
6046376966SJonas Devlieghere   }
6146376966SJonas Devlieghere   ErrorOr<std::unique_ptr<vfs::File>>
openFileForRead(const Twine & Path)6246376966SJonas Devlieghere   openFileForRead(const Twine &Path) override {
6346376966SJonas Devlieghere     auto S = status(Path);
6446376966SJonas Devlieghere     if (S)
6546376966SJonas Devlieghere       return std::unique_ptr<vfs::File>(new DummyFile{*S});
6646376966SJonas Devlieghere     return S.getError();
6746376966SJonas Devlieghere   }
getCurrentWorkingDirectory() const6846376966SJonas Devlieghere   llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
6946376966SJonas Devlieghere     return cwd;
7046376966SJonas Devlieghere   }
setCurrentWorkingDirectory(const Twine & Path)7146376966SJonas Devlieghere   std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
7246376966SJonas Devlieghere     cwd = Path.str();
7346376966SJonas Devlieghere     return std::error_code();
7446376966SJonas Devlieghere   }
7546376966SJonas Devlieghere   // Map any symlink to "/symlink".
getRealPath(const Twine & Path,SmallVectorImpl<char> & Output)76f3cae3abSKadir Cetinkaya   std::error_code getRealPath(const Twine &Path,
77446d38c6SJan Svoboda                               SmallVectorImpl<char> &Output) override {
7846376966SJonas Devlieghere     auto I = FilesAndDirs.find(Path.str());
7946376966SJonas Devlieghere     if (I == FilesAndDirs.end())
8046376966SJonas Devlieghere       return make_error_code(llvm::errc::no_such_file_or_directory);
8146376966SJonas Devlieghere     if (I->second.isSymlink()) {
8246376966SJonas Devlieghere       Output.clear();
8346376966SJonas Devlieghere       Twine("/symlink").toVector(Output);
8446376966SJonas Devlieghere       return std::error_code();
8546376966SJonas Devlieghere     }
8646376966SJonas Devlieghere     Output.clear();
8746376966SJonas Devlieghere     Path.toVector(Output);
8846376966SJonas Devlieghere     return std::error_code();
8946376966SJonas Devlieghere   }
9046376966SJonas Devlieghere 
9146376966SJonas Devlieghere   struct DirIterImpl : public llvm::vfs::detail::DirIterImpl {
9246376966SJonas Devlieghere     std::map<std::string, vfs::Status> &FilesAndDirs;
9346376966SJonas Devlieghere     std::map<std::string, vfs::Status>::iterator I;
9446376966SJonas Devlieghere     std::string Path;
isInPath__anonab014d540111::DummyFileSystem::DirIterImpl9546376966SJonas Devlieghere     bool isInPath(StringRef S) {
96*5232cec8SNicolas van Kempen       if (Path.size() < S.size() && S.starts_with(Path)) {
9746376966SJonas Devlieghere         auto LastSep = S.find_last_of('/');
9846376966SJonas Devlieghere         if (LastSep == Path.size() || LastSep == Path.size() - 1)
9946376966SJonas Devlieghere           return true;
10046376966SJonas Devlieghere       }
10146376966SJonas Devlieghere       return false;
10246376966SJonas Devlieghere     }
DirIterImpl__anonab014d540111::DummyFileSystem::DirIterImpl10346376966SJonas Devlieghere     DirIterImpl(std::map<std::string, vfs::Status> &FilesAndDirs,
10446376966SJonas Devlieghere                 const Twine &_Path)
10546376966SJonas Devlieghere         : FilesAndDirs(FilesAndDirs), I(FilesAndDirs.begin()),
10646376966SJonas Devlieghere           Path(_Path.str()) {
10746376966SJonas Devlieghere       for (; I != FilesAndDirs.end(); ++I) {
10846376966SJonas Devlieghere         if (isInPath(I->first)) {
109adcd0268SBenjamin Kramer           CurrentEntry = vfs::directory_entry(std::string(I->second.getName()),
110adcd0268SBenjamin Kramer                                               I->second.getType());
11146376966SJonas Devlieghere           break;
11246376966SJonas Devlieghere         }
11346376966SJonas Devlieghere       }
11446376966SJonas Devlieghere     }
increment__anonab014d540111::DummyFileSystem::DirIterImpl11546376966SJonas Devlieghere     std::error_code increment() override {
11646376966SJonas Devlieghere       ++I;
11746376966SJonas Devlieghere       for (; I != FilesAndDirs.end(); ++I) {
11846376966SJonas Devlieghere         if (isInPath(I->first)) {
119adcd0268SBenjamin Kramer           CurrentEntry = vfs::directory_entry(std::string(I->second.getName()),
120adcd0268SBenjamin Kramer                                               I->second.getType());
12146376966SJonas Devlieghere           break;
12246376966SJonas Devlieghere         }
12346376966SJonas Devlieghere       }
12446376966SJonas Devlieghere       if (I == FilesAndDirs.end())
12546376966SJonas Devlieghere         CurrentEntry = vfs::directory_entry();
12646376966SJonas Devlieghere       return std::error_code();
12746376966SJonas Devlieghere     }
12846376966SJonas Devlieghere   };
12946376966SJonas Devlieghere 
dir_begin(const Twine & Dir,std::error_code & EC)13046376966SJonas Devlieghere   vfs::directory_iterator dir_begin(const Twine &Dir,
13146376966SJonas Devlieghere                                     std::error_code &EC) override {
13246376966SJonas Devlieghere     return vfs::directory_iterator(
13346376966SJonas Devlieghere         std::make_shared<DirIterImpl>(FilesAndDirs, Dir));
13446376966SJonas Devlieghere   }
13546376966SJonas Devlieghere 
addEntry(StringRef Path,const vfs::Status & Status)13646376966SJonas Devlieghere   void addEntry(StringRef Path, const vfs::Status &Status) {
137adcd0268SBenjamin Kramer     FilesAndDirs[std::string(Path)] = Status;
13846376966SJonas Devlieghere   }
13946376966SJonas Devlieghere 
addRegularFile(StringRef Path,sys::fs::perms Perms=sys::fs::all_all)14046376966SJonas Devlieghere   void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
14146376966SJonas Devlieghere     vfs::Status S(Path, UniqueID(FSID, FileID++),
14246376966SJonas Devlieghere                   std::chrono::system_clock::now(), 0, 0, 1024,
14346376966SJonas Devlieghere                   sys::fs::file_type::regular_file, Perms);
14446376966SJonas Devlieghere     addEntry(Path, S);
14546376966SJonas Devlieghere   }
14646376966SJonas Devlieghere 
addDirectory(StringRef Path,sys::fs::perms Perms=sys::fs::all_all)14746376966SJonas Devlieghere   void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
14846376966SJonas Devlieghere     vfs::Status S(Path, UniqueID(FSID, FileID++),
14946376966SJonas Devlieghere                   std::chrono::system_clock::now(), 0, 0, 0,
15046376966SJonas Devlieghere                   sys::fs::file_type::directory_file, Perms);
15146376966SJonas Devlieghere     addEntry(Path, S);
15246376966SJonas Devlieghere   }
15346376966SJonas Devlieghere 
addSymlink(StringRef Path)15446376966SJonas Devlieghere   void addSymlink(StringRef Path) {
15546376966SJonas Devlieghere     vfs::Status S(Path, UniqueID(FSID, FileID++),
15646376966SJonas Devlieghere                   std::chrono::system_clock::now(), 0, 0, 0,
15746376966SJonas Devlieghere                   sys::fs::file_type::symlink_file, sys::fs::all_all);
15846376966SJonas Devlieghere     addEntry(Path, S);
15946376966SJonas Devlieghere   }
1602c1108f4SJason Molenda 
addBrokenSymlink(StringRef Path)1612c1108f4SJason Molenda   void addBrokenSymlink(StringRef Path) {
1622c1108f4SJason Molenda     vfs::Status S(Path, UniqueID(FSID, FileID++),
1632c1108f4SJason Molenda                   std::chrono::system_clock::now(), 0, 0, 0,
1642c1108f4SJason Molenda                   sys::fs::file_type::symlink_file, sys::fs::no_perms);
1652c1108f4SJason Molenda     addEntry(Path, S);
1662c1108f4SJason Molenda   }
16746376966SJonas Devlieghere };
16846376966SJonas Devlieghere } // namespace
1691408bf72SPavel Labath 
TEST(FileSystemTest,FileAndDirectoryComponents)1701408bf72SPavel Labath TEST(FileSystemTest, FileAndDirectoryComponents) {
1711408bf72SPavel Labath   using namespace std::chrono;
17246376966SJonas Devlieghere   FileSystem fs;
17346376966SJonas Devlieghere 
1748f3be7a3SJonas Devlieghere #ifdef _WIN32
1758f3be7a3SJonas Devlieghere   FileSpec fs1("C:\\FILE\\THAT\\DOES\\NOT\\EXIST.TXT");
1768f3be7a3SJonas Devlieghere #else
1778f3be7a3SJonas Devlieghere   FileSpec fs1("/file/that/does/not/exist.txt");
1788f3be7a3SJonas Devlieghere #endif
1798f3be7a3SJonas Devlieghere   FileSpec fs2(TestMainArgv0);
1808f3be7a3SJonas Devlieghere 
1818f3be7a3SJonas Devlieghere   fs.Resolve(fs2);
1828f3be7a3SJonas Devlieghere 
18346376966SJonas Devlieghere   EXPECT_EQ(system_clock::time_point(), fs.GetModificationTime(fs1));
1841408bf72SPavel Labath   EXPECT_LT(system_clock::time_point() + hours(24 * 365 * 20),
18546376966SJonas Devlieghere             fs.GetModificationTime(fs2));
18646376966SJonas Devlieghere }
18746376966SJonas Devlieghere 
GetSimpleDummyFS()18846376966SJonas Devlieghere static IntrusiveRefCntPtr<DummyFileSystem> GetSimpleDummyFS() {
18946376966SJonas Devlieghere   IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
19046376966SJonas Devlieghere   D->addRegularFile("/foo");
19146376966SJonas Devlieghere   D->addDirectory("/bar");
19246376966SJonas Devlieghere   D->addSymlink("/baz");
1932c1108f4SJason Molenda   D->addBrokenSymlink("/lux");
19446376966SJonas Devlieghere   D->addRegularFile("/qux", ~sys::fs::perms::all_read);
19546376966SJonas Devlieghere   D->setCurrentWorkingDirectory("/");
19646376966SJonas Devlieghere   return D;
19746376966SJonas Devlieghere }
19846376966SJonas Devlieghere 
TEST(FileSystemTest,Exists)19946376966SJonas Devlieghere TEST(FileSystemTest, Exists) {
20046376966SJonas Devlieghere   FileSystem fs(GetSimpleDummyFS());
20146376966SJonas Devlieghere 
20246376966SJonas Devlieghere   EXPECT_TRUE(fs.Exists("/foo"));
2038f3be7a3SJonas Devlieghere   EXPECT_TRUE(fs.Exists(FileSpec("/foo", FileSpec::Style::posix)));
20446376966SJonas Devlieghere }
20546376966SJonas Devlieghere 
TEST(FileSystemTest,Readable)20646376966SJonas Devlieghere TEST(FileSystemTest, Readable) {
20746376966SJonas Devlieghere   FileSystem fs(GetSimpleDummyFS());
20846376966SJonas Devlieghere 
20946376966SJonas Devlieghere   EXPECT_TRUE(fs.Readable("/foo"));
2108f3be7a3SJonas Devlieghere   EXPECT_TRUE(fs.Readable(FileSpec("/foo", FileSpec::Style::posix)));
21146376966SJonas Devlieghere 
21246376966SJonas Devlieghere   EXPECT_FALSE(fs.Readable("/qux"));
2138f3be7a3SJonas Devlieghere   EXPECT_FALSE(fs.Readable(FileSpec("/qux", FileSpec::Style::posix)));
21446376966SJonas Devlieghere }
21546376966SJonas Devlieghere 
TEST(FileSystemTest,GetByteSize)21646376966SJonas Devlieghere TEST(FileSystemTest, GetByteSize) {
21746376966SJonas Devlieghere   FileSystem fs(GetSimpleDummyFS());
21846376966SJonas Devlieghere 
21946376966SJonas Devlieghere   EXPECT_EQ((uint64_t)1024, fs.GetByteSize("/foo"));
22046376966SJonas Devlieghere   EXPECT_EQ((uint64_t)1024,
2218f3be7a3SJonas Devlieghere             fs.GetByteSize(FileSpec("/foo", FileSpec::Style::posix)));
22246376966SJonas Devlieghere }
22346376966SJonas Devlieghere 
TEST(FileSystemTest,GetPermissions)22446376966SJonas Devlieghere TEST(FileSystemTest, GetPermissions) {
22546376966SJonas Devlieghere   FileSystem fs(GetSimpleDummyFS());
22646376966SJonas Devlieghere 
22746376966SJonas Devlieghere   EXPECT_EQ(sys::fs::all_all, fs.GetPermissions("/foo"));
22846376966SJonas Devlieghere   EXPECT_EQ(sys::fs::all_all,
2298f3be7a3SJonas Devlieghere             fs.GetPermissions(FileSpec("/foo", FileSpec::Style::posix)));
23046376966SJonas Devlieghere }
23146376966SJonas Devlieghere 
TEST(FileSystemTest,MakeAbsolute)23246376966SJonas Devlieghere TEST(FileSystemTest, MakeAbsolute) {
23346376966SJonas Devlieghere   FileSystem fs(GetSimpleDummyFS());
23446376966SJonas Devlieghere 
23546376966SJonas Devlieghere   {
23646376966SJonas Devlieghere     StringRef foo_relative = "foo";
23746376966SJonas Devlieghere     SmallString<16> foo(foo_relative);
23846376966SJonas Devlieghere     auto EC = fs.MakeAbsolute(foo);
23946376966SJonas Devlieghere     EXPECT_FALSE(EC);
24046376966SJonas Devlieghere     EXPECT_TRUE(foo.equals("/foo"));
24146376966SJonas Devlieghere   }
24246376966SJonas Devlieghere 
24346376966SJonas Devlieghere   {
2448f3be7a3SJonas Devlieghere     FileSpec file_spec("foo");
24546376966SJonas Devlieghere     auto EC = fs.MakeAbsolute(file_spec);
24646376966SJonas Devlieghere     EXPECT_FALSE(EC);
247ee1eb528SJonas Devlieghere     EXPECT_EQ(FileSpec("/foo"), file_spec);
24846376966SJonas Devlieghere   }
24946376966SJonas Devlieghere }
25046376966SJonas Devlieghere 
TEST(FileSystemTest,Resolve)25146376966SJonas Devlieghere TEST(FileSystemTest, Resolve) {
25246376966SJonas Devlieghere   FileSystem fs(GetSimpleDummyFS());
25346376966SJonas Devlieghere 
25446376966SJonas Devlieghere   {
25546376966SJonas Devlieghere     StringRef foo_relative = "foo";
25646376966SJonas Devlieghere     SmallString<16> foo(foo_relative);
25746376966SJonas Devlieghere     fs.Resolve(foo);
25846376966SJonas Devlieghere     EXPECT_TRUE(foo.equals("/foo"));
25946376966SJonas Devlieghere   }
26046376966SJonas Devlieghere 
26146376966SJonas Devlieghere   {
2628f3be7a3SJonas Devlieghere     FileSpec file_spec("foo");
26346376966SJonas Devlieghere     fs.Resolve(file_spec);
264ee1eb528SJonas Devlieghere     EXPECT_EQ(FileSpec("/foo"), file_spec);
26546376966SJonas Devlieghere   }
26646376966SJonas Devlieghere 
26746376966SJonas Devlieghere   {
26846376966SJonas Devlieghere     StringRef foo_relative = "bogus";
26946376966SJonas Devlieghere     SmallString<16> foo(foo_relative);
27046376966SJonas Devlieghere     fs.Resolve(foo);
27146376966SJonas Devlieghere     EXPECT_TRUE(foo.equals("bogus"));
27246376966SJonas Devlieghere   }
27346376966SJonas Devlieghere 
27446376966SJonas Devlieghere   {
2758f3be7a3SJonas Devlieghere     FileSpec file_spec("bogus");
27646376966SJonas Devlieghere     fs.Resolve(file_spec);
277ee1eb528SJonas Devlieghere     EXPECT_EQ(FileSpec("bogus"), file_spec);
27846376966SJonas Devlieghere   }
27946376966SJonas Devlieghere }
2809ca491daSJonas Devlieghere 
2819ca491daSJonas Devlieghere FileSystem::EnumerateDirectoryResult
VFSCallback(void * baton,llvm::sys::fs::file_type file_type,llvm::StringRef path)2829ca491daSJonas Devlieghere VFSCallback(void *baton, llvm::sys::fs::file_type file_type,
2839ca491daSJonas Devlieghere             llvm::StringRef path) {
2849ca491daSJonas Devlieghere   auto visited = static_cast<std::vector<std::string> *>(baton);
2859ca491daSJonas Devlieghere   visited->push_back(path.str());
2869ca491daSJonas Devlieghere   return FileSystem::eEnumerateDirectoryResultNext;
2879ca491daSJonas Devlieghere }
2889ca491daSJonas Devlieghere 
TEST(FileSystemTest,EnumerateDirectory)2899ca491daSJonas Devlieghere TEST(FileSystemTest, EnumerateDirectory) {
2909ca491daSJonas Devlieghere   FileSystem fs(GetSimpleDummyFS());
2919ca491daSJonas Devlieghere 
2929ca491daSJonas Devlieghere   std::vector<std::string> visited;
2939ca491daSJonas Devlieghere 
2949ca491daSJonas Devlieghere   constexpr bool find_directories = true;
2959ca491daSJonas Devlieghere   constexpr bool find_files = true;
2969ca491daSJonas Devlieghere   constexpr bool find_other = true;
2979ca491daSJonas Devlieghere 
2989ca491daSJonas Devlieghere   fs.EnumerateDirectory("/", find_directories, find_files, find_other,
2999ca491daSJonas Devlieghere                         VFSCallback, &visited);
3009ca491daSJonas Devlieghere 
3019ca491daSJonas Devlieghere   EXPECT_THAT(visited,
3029ca491daSJonas Devlieghere               testing::UnorderedElementsAre("/foo", "/bar", "/baz", "/qux"));
3039ca491daSJonas Devlieghere }
3042fce1137SLawrence D'Anna 
TEST(FileSystemTest,OpenErrno)3052fce1137SLawrence D'Anna TEST(FileSystemTest, OpenErrno) {
3062fce1137SLawrence D'Anna #ifdef _WIN32
3072fce1137SLawrence D'Anna   FileSpec spec("C:\\FILE\\THAT\\DOES\\NOT\\EXIST.TXT");
3082fce1137SLawrence D'Anna #else
3092fce1137SLawrence D'Anna   FileSpec spec("/file/that/does/not/exist.txt");
3102fce1137SLawrence D'Anna #endif
3112fce1137SLawrence D'Anna   FileSystem fs;
31214735cabSMichał Górny   auto file = fs.Open(spec, File::eOpenOptionReadOnly, 0, true);
3132fce1137SLawrence D'Anna   ASSERT_FALSE(file);
3142fce1137SLawrence D'Anna   std::error_code code = errorToErrorCode(file.takeError());
3152fce1137SLawrence D'Anna   EXPECT_EQ(code.category(), std::system_category());
3162fce1137SLawrence D'Anna   EXPECT_EQ(code.value(), ENOENT);
3172fce1137SLawrence D'Anna }
3182fce1137SLawrence D'Anna 
TEST(FileSystemTest,EmptyTest)319d144087cSJonas Devlieghere TEST(FileSystemTest, EmptyTest) {
320d144087cSJonas Devlieghere   FileSpec spec;
321d144087cSJonas Devlieghere   FileSystem fs;
322d144087cSJonas Devlieghere 
323d144087cSJonas Devlieghere   {
324d144087cSJonas Devlieghere     std::error_code ec;
325d144087cSJonas Devlieghere     fs.DirBegin(spec, ec);
326d144087cSJonas Devlieghere     EXPECT_EQ(ec.category(), std::system_category());
327d144087cSJonas Devlieghere     EXPECT_EQ(ec.value(), ENOENT);
328d144087cSJonas Devlieghere   }
329d144087cSJonas Devlieghere 
330d144087cSJonas Devlieghere   {
331d144087cSJonas Devlieghere     llvm::ErrorOr<vfs::Status> status = fs.GetStatus(spec);
332d144087cSJonas Devlieghere     ASSERT_FALSE(status);
333d144087cSJonas Devlieghere     EXPECT_EQ(status.getError().category(), std::system_category());
334d144087cSJonas Devlieghere     EXPECT_EQ(status.getError().value(), ENOENT);
335d144087cSJonas Devlieghere   }
336d144087cSJonas Devlieghere 
337d144087cSJonas Devlieghere   EXPECT_EQ(sys::TimePoint<>(), fs.GetModificationTime(spec));
338d144087cSJonas Devlieghere   EXPECT_EQ(static_cast<uint64_t>(0), fs.GetByteSize(spec));
339d144087cSJonas Devlieghere   EXPECT_EQ(llvm::sys::fs::perms::perms_not_known, fs.GetPermissions(spec));
340d144087cSJonas Devlieghere   EXPECT_FALSE(fs.Exists(spec));
341d144087cSJonas Devlieghere   EXPECT_FALSE(fs.Readable(spec));
342d144087cSJonas Devlieghere   EXPECT_FALSE(fs.IsDirectory(spec));
343d144087cSJonas Devlieghere   EXPECT_FALSE(fs.IsLocal(spec));
344d144087cSJonas Devlieghere }
345