1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++98, c++03 11 12 // <experimental/filesystem> 13 14 // class directory_iterator 15 16 // 17 // explicit recursive_directory_iterator(const path& p); 18 // recursive_directory_iterator(const path& p, directory_options options); 19 // recursive_directory_iterator(const path& p, error_code& ec) noexcept; 20 // recursive_directory_iterator(const path& p, directory_options options, error_code& ec) noexcept; 21 22 23 #include <experimental/filesystem> 24 #include <type_traits> 25 #include <set> 26 #include <cassert> 27 28 #include "test_macros.h" 29 #include "rapid-cxx-test.hpp" 30 #include "filesystem_test_helper.hpp" 31 32 using namespace std::experimental::filesystem; 33 34 using RDI = recursive_directory_iterator; 35 36 TEST_SUITE(recursive_directory_iterator_constructor_tests) 37 38 TEST_CASE(test_constructor_signatures) 39 { 40 using D = recursive_directory_iterator; 41 42 // explicit directory_iterator(path const&); 43 static_assert(!std::is_convertible<path, D>::value, ""); 44 static_assert(std::is_constructible<D, path>::value, ""); 45 static_assert(!std::is_nothrow_constructible<D, path>::value, ""); 46 47 // directory_iterator(path const&, error_code&) noexcept 48 static_assert(std::is_nothrow_constructible<D, path, std::error_code&>::value, ""); 49 50 // directory_iterator(path const&, directory_options); 51 static_assert(std::is_constructible<D, path, directory_options>::value, ""); 52 static_assert(!std::is_nothrow_constructible<D, path, directory_options>::value, ""); 53 54 // directory_iterator(path const&, directory_options, error_code&) noexcept 55 static_assert(std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, ""); 56 } 57 58 TEST_CASE(test_construction_from_bad_path) 59 { 60 std::error_code ec; 61 directory_options opts = directory_options::none; 62 const RDI endIt; 63 64 const path testPaths[] = { StaticEnv::DNE, StaticEnv::BadSymlink }; 65 for (path const& testPath : testPaths) 66 { 67 { 68 RDI it(testPath, ec); 69 TEST_CHECK(ec); 70 TEST_CHECK(it == endIt); 71 } 72 { 73 RDI it(testPath, opts, ec); 74 TEST_CHECK(ec); 75 TEST_CHECK(it == endIt); 76 } 77 { 78 TEST_CHECK_THROW(filesystem_error, RDI(testPath)); 79 TEST_CHECK_THROW(filesystem_error, RDI(testPath, opts)); 80 } 81 } 82 } 83 84 TEST_CASE(access_denied_test_case) 85 { 86 using namespace std::experimental::filesystem; 87 scoped_test_env env; 88 path const testDir = env.make_env_path("dir1"); 89 path const testFile = testDir / "testFile"; 90 env.create_dir(testDir); 91 env.create_file(testFile, 42); 92 93 // Test that we can iterator over the directory before changing the perms 94 { 95 RDI it(testDir); 96 TEST_REQUIRE(it != RDI{}); 97 } 98 99 // Change the permissions so we can no longer iterate 100 permissions(testDir, perms::none); 101 102 // Check that the construction fails when skip_permissions_denied is 103 // not given. 104 { 105 std::error_code ec; 106 RDI it(testDir, ec); 107 TEST_REQUIRE(ec); 108 TEST_CHECK(it == RDI{}); 109 } 110 // Check that construction does not report an error when 111 // 'skip_permissions_denied' is given. 112 { 113 std::error_code ec; 114 RDI it(testDir, directory_options::skip_permission_denied, ec); 115 TEST_REQUIRE(!ec); 116 TEST_CHECK(it == RDI{}); 117 } 118 } 119 120 121 TEST_CASE(access_denied_to_file_test_case) 122 { 123 using namespace std::experimental::filesystem; 124 scoped_test_env env; 125 path const testFile = env.make_env_path("file1"); 126 env.create_file(testFile, 42); 127 128 // Change the permissions so we can no longer iterate 129 permissions(testFile, perms::none); 130 131 // Check that the construction fails when skip_permissions_denied is 132 // not given. 133 { 134 std::error_code ec; 135 RDI it(testFile, ec); 136 TEST_REQUIRE(ec); 137 TEST_CHECK(it == RDI{}); 138 } 139 // Check that construction still fails when 'skip_permissions_denied' is given 140 // because we tried to open a file and not a directory. 141 { 142 std::error_code ec; 143 RDI it(testFile, directory_options::skip_permission_denied, ec); 144 TEST_REQUIRE(ec); 145 TEST_CHECK(it == RDI{}); 146 } 147 } 148 149 TEST_CASE(test_open_on_empty_directory_equals_end) 150 { 151 scoped_test_env env; 152 const path testDir = env.make_env_path("dir1"); 153 env.create_dir(testDir); 154 155 const RDI endIt; 156 { 157 std::error_code ec; 158 RDI it(testDir, ec); 159 TEST_CHECK(!ec); 160 TEST_CHECK(it == endIt); 161 } 162 { 163 RDI it(testDir); 164 TEST_CHECK(it == endIt); 165 } 166 } 167 168 TEST_CASE(test_open_on_directory_succeeds) 169 { 170 const path testDir = StaticEnv::Dir; 171 std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList), 172 std::end( StaticEnv::DirIterationList)); 173 const RDI endIt{}; 174 175 { 176 std::error_code ec; 177 RDI it(testDir, ec); 178 TEST_REQUIRE(!ec); 179 TEST_CHECK(it != endIt); 180 TEST_CHECK(dir_contents.count(*it)); 181 } 182 { 183 RDI it(testDir); 184 TEST_CHECK(it != endIt); 185 TEST_CHECK(dir_contents.count(*it)); 186 } 187 } 188 189 TEST_CASE(test_open_on_file_fails) 190 { 191 const path testFile = StaticEnv::File; 192 const RDI endIt{}; 193 { 194 std::error_code ec; 195 RDI it(testFile, ec); 196 TEST_REQUIRE(ec); 197 TEST_CHECK(it == endIt); 198 } 199 { 200 TEST_CHECK_THROW(filesystem_error, RDI(testFile)); 201 } 202 } 203 204 TEST_CASE(test_options_post_conditions) 205 { 206 const path goodDir = StaticEnv::Dir; 207 const path badDir = StaticEnv::DNE; 208 209 { 210 std::error_code ec; 211 212 RDI it1(goodDir, ec); 213 TEST_REQUIRE(!ec); 214 TEST_CHECK(it1.options() == directory_options::none); 215 216 RDI it2(badDir, ec); 217 TEST_REQUIRE(ec); 218 TEST_REQUIRE(it2 == RDI{}); 219 } 220 { 221 std::error_code ec; 222 const directory_options opts = directory_options::skip_permission_denied; 223 224 RDI it1(goodDir, opts, ec); 225 TEST_REQUIRE(!ec); 226 TEST_CHECK(it1.options() == opts); 227 228 RDI it2(badDir, opts, ec); 229 TEST_REQUIRE(ec); 230 TEST_REQUIRE(it2 == RDI{}); 231 } 232 { 233 RDI it(goodDir); 234 TEST_CHECK(it.options() == directory_options::none); 235 } 236 { 237 const directory_options opts = directory_options::follow_directory_symlink; 238 RDI it(goodDir, opts); 239 TEST_CHECK(it.options() == opts); 240 } 241 } 242 TEST_SUITE_END() 243