diff options
author | Juergen Ributzka <juergen@apple.com> | 2017-03-13 21:34:07 +0000 |
---|---|---|
committer | Juergen Ributzka <juergen@apple.com> | 2017-03-13 21:34:07 +0000 |
commit | e7d0fa68f38f2ad8aa567f9c5ca4871f508cdae7 (patch) | |
tree | cee30a64c8926e9937f5fbb101b9b3210d3093be | |
parent | 55e6f10d699edd8b6a9f815e70b4e790e00584f9 (diff) | |
download | llvm-e7d0fa68f38f2ad8aa567f9c5ca4871f508cdae7.zip llvm-e7d0fa68f38f2ad8aa567f9c5ca4871f508cdae7.tar.gz llvm-e7d0fa68f38f2ad8aa567f9c5ca4871f508cdae7.tar.bz2 |
[Support] Test directory iterators and recursive directory iterators with broken symlinks.
This commit adds a unit test to the file system tests to verify the behavior of
the directory iterator and recursive directory iterator with broken symlinks.
This test is Unix only.
llvm-svn: 297669
-rw-r--r-- | llvm/unittests/Support/Path.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp index c9c98f5..ad5fbff 100644 --- a/llvm/unittests/Support/Path.cpp +++ b/llvm/unittests/Support/Path.cpp @@ -778,6 +778,84 @@ TEST_F(FileSystemTest, DirectoryIteration) { ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel")); } +#ifdef LLVM_ON_UNIX +TEST_F(FileSystemTest, BrokenSymlinkDirectoryIteration) { + // Create a known hierarchy to recurse over. + ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory) + "/symlink")); + ASSERT_NO_ERROR( + fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/a")); + ASSERT_NO_ERROR( + fs::create_directories(Twine(TestDirectory) + "/symlink/b/bb")); + ASSERT_NO_ERROR( + fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/b/ba")); + ASSERT_NO_ERROR( + fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/b/bc")); + ASSERT_NO_ERROR( + fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/c")); + ASSERT_NO_ERROR( + fs::create_directories(Twine(TestDirectory) + "/symlink/d/dd/ddd")); + ASSERT_NO_ERROR(fs::create_link(Twine(TestDirectory) + "/symlink/d/dd", + Twine(TestDirectory) + "/symlink/d/da")); + ASSERT_NO_ERROR( + fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/e")); + + typedef std::vector<std::string> v_t; + v_t visited; + + // The directory iterator doesn't stat the file, so we should be able to + // iterate over the whole directory. + std::error_code ec; + for (fs::directory_iterator i(Twine(TestDirectory) + "/symlink", ec), e; + i != e; i.increment(ec)) { + ASSERT_NO_ERROR(ec); + visited.push_back(path::filename(i->path())); + } + std::sort(visited.begin(), visited.end()); + v_t expected = {"a", "b", "c", "d", "e"}; + ASSERT_TRUE(visited.size() == expected.size()); + ASSERT_TRUE(std::equal(visited.begin(), visited.end(), expected.begin())); + visited.clear(); + + // The recursive directory iterator has to stat the file, so we need to skip + // the broken symlinks. + for (fs::recursive_directory_iterator + i(Twine(TestDirectory) + "/symlink", ec), + e; + i != e; i.increment(ec)) { + ASSERT_NO_ERROR(ec); + + fs::file_status status; + if (i->status(status) == std::errc::no_such_file_or_directory) { + i.no_push(); + continue; + } + + visited.push_back(path::filename(i->path())); + } + std::sort(visited.begin(), visited.end()); + expected = {"b", "bb", "d", "da", "dd", "ddd", "ddd"}; + ASSERT_TRUE(visited.size() == expected.size()); + ASSERT_TRUE(std::equal(visited.begin(), visited.end(), expected.begin())); + visited.clear(); + + // This recursive directory iterator doesn't follow symlinks, so we don't need + // to skip them. + for (fs::recursive_directory_iterator + i(Twine(TestDirectory) + "/symlink", ec, /*follow_symlinks=*/false), + e; + i != e; i.increment(ec)) { + ASSERT_NO_ERROR(ec); + visited.push_back(path::filename(i->path())); + } + + expected = {"a", "b", "ba", "bb", "bc", "c", "d", "da", "dd", "ddd", "e"}; + ASSERT_TRUE(visited.size() == expected.size()); + ASSERT_TRUE(std::equal(visited.begin(), visited.end(), expected.begin())); + + ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/symlink")); +} +#endif + TEST_F(FileSystemTest, Remove) { SmallString<64> BaseDir; SmallString<64> Paths[4]; |