diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2020-10-15 10:36:00 -0400 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2020-10-20 13:40:23 -0400 |
commit | 729d7d23282e9b00eaa7a5f35a4224929d73d3a4 (patch) | |
tree | bdb84864d2aded03764c2663f5208fd99fae8c7f /clang/unittests/Basic/FileManagerTest.cpp | |
parent | 51d1d585e5838ea0f02f1271f7543c4e43639969 (diff) | |
download | llvm-729d7d23282e9b00eaa7a5f35a4224929d73d3a4.zip llvm-729d7d23282e9b00eaa7a5f35a4224929d73d3a4.tar.gz llvm-729d7d23282e9b00eaa7a5f35a4224929d73d3a4.tar.bz2 |
FileManager: Test FileManager::getFileRef
Add a test demonstrating `getFileRef`'s behaviour, which isn't obvious
from code inspection when it's handling a redirected file.
Differential Revision: https://reviews.llvm.org/D89469
Diffstat (limited to 'clang/unittests/Basic/FileManagerTest.cpp')
-rw-r--r-- | clang/unittests/Basic/FileManagerTest.cpp | 75 |
1 files changed, 70 insertions, 5 deletions
diff --git a/clang/unittests/Basic/FileManagerTest.cpp b/clang/unittests/Basic/FileManagerTest.cpp index 9195cc0..dfb79b4 100644 --- a/clang/unittests/Basic/FileManagerTest.cpp +++ b/clang/unittests/Basic/FileManagerTest.cpp @@ -28,17 +28,28 @@ private: // not in this map is considered to not exist in the file system. llvm::StringMap<llvm::vfs::Status, llvm::BumpPtrAllocator> StatCalls; - void InjectFileOrDirectory(const char *Path, ino_t INode, bool IsFile) { + void InjectFileOrDirectory(const char *Path, ino_t INode, bool IsFile, + const char *StatPath) { #ifndef _WIN32 SmallString<128> NormalizedPath(Path); llvm::sys::path::native(NormalizedPath); Path = NormalizedPath.c_str(); + + SmallString<128> NormalizedStatPath; + if (StatPath) { + NormalizedStatPath = StatPath; + llvm::sys::path::native(NormalizedStatPath); + StatPath = NormalizedStatPath.c_str(); + } #endif + if (!StatPath) + StatPath = Path; + auto fileType = IsFile ? llvm::sys::fs::file_type::regular_file : llvm::sys::fs::file_type::directory_file; - llvm::vfs::Status Status(Path, llvm::sys::fs::UniqueID(1, INode), + llvm::vfs::Status Status(StatPath, llvm::sys::fs::UniqueID(1, INode), /*MTime*/{}, /*User*/0, /*Group*/0, /*Size*/0, fileType, llvm::sys::fs::perms::all_all); @@ -47,13 +58,14 @@ private: public: // Inject a file with the given inode value to the fake file system. - void InjectFile(const char *Path, ino_t INode) { - InjectFileOrDirectory(Path, INode, /*IsFile=*/true); + void InjectFile(const char *Path, ino_t INode, + const char *StatPath = nullptr) { + InjectFileOrDirectory(Path, INode, /*IsFile=*/true, StatPath); } // Inject a directory with the given inode value to the fake file system. void InjectDirectory(const char *Path, ino_t INode) { - InjectFileOrDirectory(Path, INode, /*IsFile=*/false); + InjectFileOrDirectory(Path, INode, /*IsFile=*/false, nullptr); } // Implement FileSystemStatCache::getStat(). @@ -249,6 +261,59 @@ TEST_F(FileManagerTest, getFileReturnsSameFileEntryForAliasedRealFiles) { EXPECT_EQ(f1 ? *f1 : nullptr, f2 ? *f2 : nullptr); + + // Check that getFileRef also does the right thing. + auto r1 = manager.getFileRef("abc/foo.cpp"); + auto r2 = manager.getFileRef("abc/bar.cpp"); + ASSERT_FALSE(!r1); + ASSERT_FALSE(!r2); + + EXPECT_EQ("abc/foo.cpp", r1->getName()); + EXPECT_EQ("abc/bar.cpp", r2->getName()); + EXPECT_EQ((f1 ? *f1 : nullptr), &r1->getFileEntry()); + EXPECT_EQ((f2 ? *f2 : nullptr), &r2->getFileEntry()); +} + +TEST_F(FileManagerTest, getFileRefReturnsCorrectNameForDifferentStatPath) { + // Inject files with the same inode, but where some files have a stat that + // gives a different name. This is adding coverage for weird stat behaviour + // triggered by the RedirectingFileSystem that FileManager::getFileRef has + // special logic for. + auto StatCache = std::make_unique<FakeStatCache>(); + StatCache->InjectDirectory("dir", 40); + StatCache->InjectFile("dir/f1.cpp", 41); + StatCache->InjectFile("dir/f1-alias.cpp", 41, "dir/f1.cpp"); + StatCache->InjectFile("dir/f2.cpp", 42); + StatCache->InjectFile("dir/f2-alias.cpp", 42, "dir/f2.cpp"); + manager.setStatCache(std::move(StatCache)); + + // With F2, test accessing the non-redirected name first. + auto F1 = manager.getFileRef("dir/f1.cpp"); + auto F1Alias = manager.getFileRef("dir/f1-alias.cpp"); + auto F1Alias2 = manager.getFileRef("dir/f1-alias.cpp"); + ASSERT_FALSE(!F1); + ASSERT_FALSE(!F1Alias); + ASSERT_FALSE(!F1Alias2); + EXPECT_EQ("dir/f1.cpp", F1->getName()); + EXPECT_EQ("dir/f1.cpp", F1->getFileEntry().getName()); + EXPECT_EQ("dir/f1.cpp", F1Alias->getName()); + EXPECT_EQ("dir/f1.cpp", F1Alias2->getName()); + EXPECT_EQ(&F1->getFileEntry(), &F1Alias->getFileEntry()); + EXPECT_EQ(&F1->getFileEntry(), &F1Alias2->getFileEntry()); + + // With F2, test accessing the redirected name first. + auto F2Alias = manager.getFileRef("dir/f2-alias.cpp"); + auto F2 = manager.getFileRef("dir/f2.cpp"); + auto F2Alias2 = manager.getFileRef("dir/f2-alias.cpp"); + ASSERT_FALSE(!F2); + ASSERT_FALSE(!F2Alias); + ASSERT_FALSE(!F2Alias2); + EXPECT_EQ("dir/f2.cpp", F2->getName()); + EXPECT_EQ("dir/f2.cpp", F2->getFileEntry().getName()); + EXPECT_EQ("dir/f2.cpp", F2Alias->getName()); + EXPECT_EQ("dir/f2.cpp", F2Alias2->getName()); + EXPECT_EQ(&F2->getFileEntry(), &F2Alias->getFileEntry()); + EXPECT_EQ(&F2->getFileEntry(), &F2Alias2->getFileEntry()); } // getFile() returns the same FileEntry for virtual files that have |