diff options
Diffstat (limited to 'test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp')
-rw-r--r-- | test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp | 248 |
1 files changed, 247 insertions, 1 deletions
diff --git a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp index 26fc3ca28d8e..ea81ee25313d 100644 --- a/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp +++ b/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp @@ -40,7 +40,7 @@ TEST_CASE(test_increment_signatures) ASSERT_NOT_NOEXCEPT(++d); ASSERT_SAME_TYPE(decltype(d.increment(ec)), recursive_directory_iterator&); - ASSERT_NOEXCEPT(d.increment(ec)); + ASSERT_NOT_NOEXCEPT(d.increment(ec)); } TEST_CASE(test_prefix_increment) @@ -237,4 +237,250 @@ TEST_CASE(access_denied_on_recursion_test_case) } } +// See llvm.org/PR35078 +TEST_CASE(test_PR35078) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + const path testFiles[] = { + env.create_dir("dir1"), + env.create_dir("dir1/dir2"), + env.create_dir("dir1/dir2/dir3"), + env.create_file("dir1/file1"), + env.create_file("dir1/dir2/dir3/file2") + }; + const path startDir = testFiles[0]; + const path permDeniedDir = testFiles[1]; + const path nestedDir = testFiles[2]; + const path nestedFile = testFiles[3]; + + // Change the permissions so we can no longer iterate + permissions(permDeniedDir, + perms::remove_perms|perms::group_exec + |perms::owner_exec|perms::others_exec); + + const std::error_code eacess_ec = + std::make_error_code(std::errc::permission_denied); + std::error_code ec = GetTestEC(); + + const recursive_directory_iterator endIt; + + auto SetupState = [&](bool AllowEAccess, bool& SeenFile3) { + SeenFile3 = false; + auto Opts = AllowEAccess ? directory_options::skip_permission_denied + : directory_options::none; + recursive_directory_iterator it(startDir, Opts, ec); + while (!ec && it != endIt && *it != nestedDir) { + if (*it == nestedFile) + SeenFile3 = true; + it.increment(ec); + } + return it; + }; + + { + bool SeenNestedFile = false; + recursive_directory_iterator it = SetupState(false, SeenNestedFile); + TEST_REQUIRE(it != endIt); + TEST_REQUIRE(*it == nestedDir); + ec = GetTestEC(); + it.increment(ec); + TEST_CHECK(ec); + TEST_CHECK(ec == eacess_ec); + TEST_CHECK(it == endIt); + } + { + bool SeenNestedFile = false; + recursive_directory_iterator it = SetupState(true, SeenNestedFile); + TEST_REQUIRE(it != endIt); + TEST_REQUIRE(*it == nestedDir); + ec = GetTestEC(); + it.increment(ec); + TEST_CHECK(!ec); + if (SeenNestedFile) { + TEST_CHECK(it == endIt); + } else { + TEST_REQUIRE(it != endIt); + TEST_CHECK(*it == nestedFile); + } + } +} + + +// See llvm.org/PR35078 +TEST_CASE(test_PR35078_with_symlink) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + const path testFiles[] = { + env.create_dir("dir1"), + env.create_file("dir1/file1"), + env.create_dir("sym_dir"), + env.create_dir("sym_dir/nested_sym_dir"), + env.create_symlink("sym_dir/nested_sym_dir", "dir1/dir2"), + env.create_dir("sym_dir/dir1"), + env.create_dir("sym_dir/dir1/dir2"), + + }; + // const unsigned TestFilesSize = sizeof(testFiles) / sizeof(testFiles[0]); + const path startDir = testFiles[0]; + const path nestedFile = testFiles[1]; + const path permDeniedDir = testFiles[2]; + const path symDir = testFiles[4]; + + // Change the permissions so we can no longer iterate + permissions(permDeniedDir, + perms::remove_perms|perms::group_exec + |perms::owner_exec|perms::others_exec); + + const std::error_code eacess_ec = + std::make_error_code(std::errc::permission_denied); + std::error_code ec = GetTestEC(); + + const recursive_directory_iterator endIt; + + auto SetupState = [&](bool AllowEAccess, bool FollowSym, bool& SeenFile3) { + SeenFile3 = false; + auto Opts = AllowEAccess ? directory_options::skip_permission_denied + : directory_options::none; + if (FollowSym) + Opts |= directory_options::follow_directory_symlink; + recursive_directory_iterator it(startDir, Opts, ec); + while (!ec && it != endIt && *it != symDir) { + std::cout << *it << std::endl; + if (*it == nestedFile) + SeenFile3 = true; + it.increment(ec); + } + return it; + }; + + struct { + bool SkipPermDenied; + bool FollowSymlinks; + bool ExpectSuccess; + } TestCases[] = { + // Passing cases + {false, false, true}, {true, true, true}, {true, false, true}, + // Failing cases + {false, true, false} + }; + for (auto TC : TestCases) { + bool SeenNestedFile = false; + recursive_directory_iterator it = SetupState(TC.SkipPermDenied, + TC.FollowSymlinks, + SeenNestedFile); + TEST_REQUIRE(!ec); + TEST_REQUIRE(it != endIt); + TEST_REQUIRE(*it == symDir); + ec = GetTestEC(); + it.increment(ec); + if (TC.ExpectSuccess) { + TEST_CHECK(!ec); + if (SeenNestedFile) { + TEST_CHECK(it == endIt); + } else { + TEST_REQUIRE(it != endIt); + TEST_CHECK(*it == nestedFile); + } + } else { + TEST_CHECK(ec); + TEST_CHECK(ec == eacess_ec); + TEST_CHECK(it == endIt); + } + } +} + + +// See llvm.org/PR35078 +TEST_CASE(test_PR35078_with_symlink_file) +{ + using namespace std::experimental::filesystem; + scoped_test_env env; + const path testFiles[] = { + env.create_dir("dir1"), + env.create_dir("dir1/dir2"), + env.create_file("dir1/file2"), + env.create_dir("sym_dir"), + env.create_dir("sym_dir/sdir1"), + env.create_file("sym_dir/sdir1/sfile1"), + env.create_symlink("sym_dir/sdir1/sfile1", "dir1/dir2/file1") + }; + const unsigned TestFilesSize = sizeof(testFiles) / sizeof(testFiles[0]); + const path startDir = testFiles[0]; + const path nestedDir = testFiles[1]; + const path nestedFile = testFiles[2]; + const path permDeniedDir = testFiles[3]; + const path symFile = testFiles[TestFilesSize - 1]; + + // Change the permissions so we can no longer iterate + permissions(permDeniedDir, + perms::remove_perms|perms::group_exec + |perms::owner_exec|perms::others_exec); + + const std::error_code eacess_ec = + std::make_error_code(std::errc::permission_denied); + std::error_code ec = GetTestEC(); + + const recursive_directory_iterator EndIt; + + auto SetupState = [&](bool AllowEAccess, bool FollowSym, bool& SeenNestedFile) { + SeenNestedFile = false; + auto Opts = AllowEAccess ? directory_options::skip_permission_denied + : directory_options::none; + if (FollowSym) + Opts |= directory_options::follow_directory_symlink; + recursive_directory_iterator it(startDir, Opts, ec); + while (!ec && it != EndIt && *it != nestedDir) { + if (*it == nestedFile) + SeenNestedFile = true; + it.increment(ec); + } + return it; + }; + + struct { + bool SkipPermDenied; + bool FollowSymlinks; + bool ExpectSuccess; + } TestCases[] = { + // Passing cases + {false, false, true}, {true, true, true}, {true, false, true}, + // Failing cases + {false, true, false} + }; + for (auto TC : TestCases){ + bool SeenNestedFile = false; + recursive_directory_iterator it = SetupState(TC.SkipPermDenied, + TC.FollowSymlinks, + SeenNestedFile); + TEST_REQUIRE(!ec); + TEST_REQUIRE(it != EndIt); + TEST_REQUIRE(*it == nestedDir); + ec = GetTestEC(); + it.increment(ec); + TEST_REQUIRE(it != EndIt); + TEST_CHECK(!ec); + TEST_CHECK(*it == symFile); + ec = GetTestEC(); + it.increment(ec); + if (TC.ExpectSuccess) { + if (!SeenNestedFile) { + TEST_CHECK(!ec); + TEST_REQUIRE(it != EndIt); + TEST_CHECK(*it == nestedFile); + ec = GetTestEC(); + it.increment(ec); + } + TEST_CHECK(!ec); + TEST_CHECK(it == EndIt); + } else { + TEST_CHECK(ec); + TEST_CHECK(ec == eacess_ec); + TEST_CHECK(it == EndIt); + } + } +} + + TEST_SUITE_END() |