@@ -41,7 +41,9 @@ struct DummyFile : public vfs::File {
41
41
class DummyFileSystem : public vfs ::FileSystem {
42
42
int FSID; // used to produce UniqueIDs
43
43
int FileID; // used to produce UniqueIDs
44
+ std::string WorkingDirectory;
44
45
std::map<std::string, vfs::Status> FilesAndDirs;
46
+ typedef std::map<std::string, vfs::Status>::const_iterator const_iterator;
45
47
46
48
static int getNextFSID () {
47
49
static int Count = 0 ;
@@ -52,8 +54,7 @@ class DummyFileSystem : public vfs::FileSystem {
52
54
DummyFileSystem () : FSID(getNextFSID()), FileID(0 ) {}
53
55
54
56
ErrorOr<vfs::Status> status (const Twine &Path) override {
55
- std::map<std::string, vfs::Status>::iterator I =
56
- FilesAndDirs.find (Path.str ());
57
+ auto I = findEntry (Path);
57
58
if (I == FilesAndDirs.end ())
58
59
return make_error_code (llvm::errc::no_such_file_or_directory);
59
60
return I->second ;
@@ -66,15 +67,16 @@ class DummyFileSystem : public vfs::FileSystem {
66
67
return S.getError ();
67
68
}
68
69
llvm::ErrorOr<std::string> getCurrentWorkingDirectory () const override {
69
- return std::string () ;
70
+ return WorkingDirectory ;
70
71
}
71
72
std::error_code setCurrentWorkingDirectory (const Twine &Path) override {
73
+ WorkingDirectory = Path.str ();
72
74
return std::error_code ();
73
75
}
74
76
// Map any symlink to "/symlink".
75
77
std::error_code getRealPath (const Twine &Path,
76
78
SmallVectorImpl<char > &Output) const override {
77
- auto I = FilesAndDirs. find (Path. str () );
79
+ auto I = findEntry (Path);
78
80
if (I == FilesAndDirs.end ())
79
81
return make_error_code (llvm::errc::no_such_file_or_directory);
80
82
if (I->second .isSymlink ()) {
@@ -136,6 +138,14 @@ class DummyFileSystem : public vfs::FileSystem {
136
138
FilesAndDirs[Path] = Status;
137
139
}
138
140
141
+ const_iterator findEntry (const Twine &Path) const {
142
+ SmallString<128 > P;
143
+ Path.toVector (P);
144
+ std::error_code EC = makeAbsolute (P);
145
+ assert (!EC);
146
+ return FilesAndDirs.find (P.str ());
147
+ }
148
+
139
149
void addRegularFile (StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
140
150
vfs::Status S (Path, UniqueID (FSID, FileID++),
141
151
std::chrono::system_clock::now (), 0 , 0 , 1024 ,
@@ -158,6 +168,12 @@ class DummyFileSystem : public vfs::FileSystem {
158
168
}
159
169
};
160
170
171
+ class ErrorDummyFileSystem : public DummyFileSystem {
172
+ std::error_code setCurrentWorkingDirectory (const Twine &Path) override {
173
+ return llvm::errc::no_such_file_or_directory;
174
+ }
175
+ };
176
+
161
177
// / Replace back-slashes by front-slashes.
162
178
std::string getPosixPath (std::string S) {
163
179
SmallString<128 > Result;
@@ -1994,3 +2010,154 @@ TEST_F(VFSFromYAMLTest, GetRealPath) {
1994
2010
EXPECT_EQ (FS->getRealPath (" /non_existing" , RealPath),
1995
2011
errc::no_such_file_or_directory);
1996
2012
}
2013
+
2014
+ TEST_F (VFSFromYAMLTest, WorkingDirectory) {
2015
+ IntrusiveRefCntPtr<DummyFileSystem> Lower (new DummyFileSystem ());
2016
+ Lower->addDirectory (" //root/" );
2017
+ Lower->addDirectory (" //root/foo" );
2018
+ Lower->addRegularFile (" //root/foo/a" );
2019
+ Lower->addRegularFile (" //root/foo/b" );
2020
+ IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString (
2021
+ " { 'use-external-names': false,\n "
2022
+ " 'roots': [\n "
2023
+ " {\n "
2024
+ " 'type': 'directory',\n "
2025
+ " 'name': '//root/',\n "
2026
+ " 'contents': [ {\n "
2027
+ " 'type': 'file',\n "
2028
+ " 'name': 'bar/a',\n "
2029
+ " 'external-contents': '//root/foo/a'\n "
2030
+ " }\n "
2031
+ " ]\n "
2032
+ " }\n "
2033
+ " ]\n "
2034
+ " }" ,
2035
+ Lower);
2036
+ ASSERT_TRUE (FS.get () != nullptr );
2037
+ std::error_code EC = FS->setCurrentWorkingDirectory (" //root/bar/" );
2038
+ ASSERT_FALSE (EC);
2039
+
2040
+ llvm::ErrorOr<std::string> WorkingDir = FS->getCurrentWorkingDirectory ();
2041
+ ASSERT_TRUE (WorkingDir);
2042
+ EXPECT_EQ (*WorkingDir, " //root/bar/" );
2043
+
2044
+ llvm::ErrorOr<vfs::Status> Status = FS->status (" ./a" );
2045
+ ASSERT_FALSE (Status.getError ());
2046
+ EXPECT_TRUE (Status->isStatusKnown ());
2047
+ EXPECT_FALSE (Status->isDirectory ());
2048
+ EXPECT_TRUE (Status->isRegularFile ());
2049
+ EXPECT_FALSE (Status->isSymlink ());
2050
+ EXPECT_FALSE (Status->isOther ());
2051
+ EXPECT_TRUE (Status->exists ());
2052
+
2053
+ EC = FS->setCurrentWorkingDirectory (" bogus" );
2054
+ ASSERT_TRUE (EC);
2055
+ WorkingDir = FS->getCurrentWorkingDirectory ();
2056
+ ASSERT_TRUE (WorkingDir);
2057
+ EXPECT_EQ (*WorkingDir, " //root/bar/" );
2058
+
2059
+ EC = FS->setCurrentWorkingDirectory (" //root/" );
2060
+ ASSERT_FALSE (EC);
2061
+ WorkingDir = FS->getCurrentWorkingDirectory ();
2062
+ ASSERT_TRUE (WorkingDir);
2063
+ EXPECT_EQ (*WorkingDir, " //root/" );
2064
+
2065
+ EC = FS->setCurrentWorkingDirectory (" bar/" );
2066
+ ASSERT_FALSE (EC);
2067
+ WorkingDir = FS->getCurrentWorkingDirectory ();
2068
+ ASSERT_TRUE (WorkingDir);
2069
+ EXPECT_EQ (*WorkingDir, " //root/bar/" );
2070
+ }
2071
+
2072
+ TEST_F (VFSFromYAMLTest, WorkingDirectoryFallthrough) {
2073
+ IntrusiveRefCntPtr<DummyFileSystem> Lower (new DummyFileSystem ());
2074
+ Lower->addDirectory (" //root/" );
2075
+ Lower->addDirectory (" //root/foo" );
2076
+ Lower->addRegularFile (" //root/foo/a" );
2077
+ Lower->addRegularFile (" //root/foo/b" );
2078
+ Lower->addRegularFile (" //root/c" );
2079
+ IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString (
2080
+ " { 'use-external-names': false,\n "
2081
+ " 'roots': [\n "
2082
+ " {\n "
2083
+ " 'type': 'directory',\n "
2084
+ " 'name': '//root/',\n "
2085
+ " 'contents': [ {\n "
2086
+ " 'type': 'file',\n "
2087
+ " 'name': 'bar/a',\n "
2088
+ " 'external-contents': '//root/foo/a'\n "
2089
+ " }\n "
2090
+ " ]\n "
2091
+ " }\n "
2092
+ " ]\n "
2093
+ " }" ,
2094
+ Lower);
2095
+ ASSERT_TRUE (FS.get () != nullptr );
2096
+ std::error_code EC = FS->setCurrentWorkingDirectory (" //root/" );
2097
+ ASSERT_FALSE (EC);
2098
+ ASSERT_TRUE (FS.get () != nullptr );
2099
+
2100
+ llvm::ErrorOr<vfs::Status> Status = FS->status (" bar/a" );
2101
+ ASSERT_FALSE (Status.getError ());
2102
+ EXPECT_TRUE (Status->exists ());
2103
+
2104
+ Status = FS->status (" foo/a" );
2105
+ ASSERT_FALSE (Status.getError ());
2106
+ EXPECT_TRUE (Status->exists ());
2107
+
2108
+ EC = FS->setCurrentWorkingDirectory (" //root/bar/" );
2109
+ ASSERT_FALSE (EC);
2110
+
2111
+ Status = FS->status (" ./a" );
2112
+ ASSERT_FALSE (Status.getError ());
2113
+ EXPECT_TRUE (Status->exists ());
2114
+
2115
+ Status = FS->status (" ./b" );
2116
+ ASSERT_TRUE (Status.getError ());
2117
+
2118
+ Status = FS->status (" ./c" );
2119
+ ASSERT_TRUE (Status.getError ());
2120
+
2121
+ EC = FS->setCurrentWorkingDirectory (" //root/" );
2122
+ ASSERT_FALSE (EC);
2123
+
2124
+ Status = FS->status (" c" );
2125
+ ASSERT_FALSE (Status.getError ());
2126
+ EXPECT_TRUE (Status->exists ());
2127
+ }
2128
+
2129
+ TEST_F (VFSFromYAMLTest, WorkingDirectoryFallthroughInvalid) {
2130
+ IntrusiveRefCntPtr<ErrorDummyFileSystem> Lower (new ErrorDummyFileSystem ());
2131
+ Lower->addDirectory (" //root/" );
2132
+ Lower->addDirectory (" //root/foo" );
2133
+ Lower->addRegularFile (" //root/foo/a" );
2134
+ Lower->addRegularFile (" //root/foo/b" );
2135
+ Lower->addRegularFile (" //root/c" );
2136
+ IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString (
2137
+ " { 'use-external-names': false,\n "
2138
+ " 'roots': [\n "
2139
+ " {\n "
2140
+ " 'type': 'directory',\n "
2141
+ " 'name': '//root/',\n "
2142
+ " 'contents': [ {\n "
2143
+ " 'type': 'file',\n "
2144
+ " 'name': 'bar/a',\n "
2145
+ " 'external-contents': '//root/foo/a'\n "
2146
+ " }\n "
2147
+ " ]\n "
2148
+ " }\n "
2149
+ " ]\n "
2150
+ " }" ,
2151
+ Lower);
2152
+ ASSERT_TRUE (FS.get () != nullptr );
2153
+ std::error_code EC = FS->setCurrentWorkingDirectory (" //root/" );
2154
+ ASSERT_FALSE (EC);
2155
+ ASSERT_TRUE (FS.get () != nullptr );
2156
+
2157
+ llvm::ErrorOr<vfs::Status> Status = FS->status (" bar/a" );
2158
+ ASSERT_FALSE (Status.getError ());
2159
+ EXPECT_TRUE (Status->exists ());
2160
+
2161
+ Status = FS->status (" foo/a" );
2162
+ ASSERT_TRUE (Status.getError ());
2163
+ }
0 commit comments