refresh.pass.cpp (9527B)
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 // <filesystem> 13 14 // class directory_entry 15 16 // directory_entry& operator=(directory_entry const&) = default; 17 // directory_entry& operator=(directory_entry&&) noexcept = default; 18 // void assign(path const&); 19 // void replace_filename(path const&); 20 21 #include "filesystem_include.hpp" 22 #include <type_traits> 23 #include <cassert> 24 25 #include "test_macros.h" 26 #include "rapid-cxx-test.hpp" 27 #include "filesystem_test_helper.hpp" 28 29 TEST_SUITE(directory_entry_mods_suite) 30 31 TEST_CASE(test_refresh_method) { 32 using namespace fs; 33 { 34 directory_entry e; 35 static_assert(noexcept(e.refresh()) == false, 36 "operation cannot be noexcept"); 37 static_assert(std::is_same<decltype(e.refresh()), void>::value, 38 "operation must return void"); 39 } 40 { 41 directory_entry e; 42 e.refresh(); 43 TEST_CHECK(!e.exists()); 44 } 45 } 46 47 TEST_CASE(test_refresh_ec_method) { 48 using namespace fs; 49 { 50 directory_entry e; 51 std::error_code ec; 52 static_assert(noexcept(e.refresh(ec)), "operation should be noexcept"); 53 static_assert(std::is_same<decltype(e.refresh(ec)), void>::value, 54 "operation must return void"); 55 } 56 { 57 directory_entry e; 58 std::error_code ec = GetTestEC(); 59 e.refresh(ec); 60 TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory)); 61 } 62 } 63 64 TEST_CASE(refresh_on_file_dne) { 65 using namespace fs; 66 scoped_test_env env; 67 const path dir = env.create_dir("dir"); 68 const path file = env.create_file("dir/file", 42); 69 70 const perms old_perms = status(dir).permissions(); 71 72 // test file doesn't exist 73 { 74 directory_entry ent(file); 75 remove(file); 76 TEST_CHECK(ent.exists()); 77 78 ent.refresh(); 79 80 permissions(dir, perms::none); 81 TEST_CHECK(!ent.exists()); 82 } 83 permissions(dir, old_perms); 84 env.create_file("dir/file", 101); 85 { 86 directory_entry ent(file); 87 remove(file); 88 TEST_CHECK(ent.exists()); 89 90 std::error_code ec = GetTestEC(); 91 ent.refresh(ec); 92 TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory)); 93 94 permissions(dir, perms::none); 95 TEST_CHECK(!ent.exists()); 96 } 97 } 98 99 void remove_if_exists(const fs::path& p) { 100 std::error_code ec; 101 remove(p, ec); 102 } 103 104 TEST_CASE(refresh_on_bad_symlink) { 105 using namespace fs; 106 scoped_test_env env; 107 const path dir = env.create_dir("dir"); 108 const path file = env.create_file("dir/file", 42); 109 const path sym = env.create_symlink("dir/file", "sym"); 110 111 const perms old_perms = status(dir).permissions(); 112 113 // test file doesn't exist 114 { 115 directory_entry ent(sym); 116 LIBCPP_ONLY(remove(file)); 117 TEST_CHECK(ent.is_symlink()); 118 TEST_CHECK(ent.is_regular_file()); 119 TEST_CHECK(ent.exists()); 120 121 remove_if_exists(file); 122 ent.refresh(); 123 124 LIBCPP_ONLY(permissions(dir, perms::none)); 125 TEST_CHECK(ent.is_symlink()); 126 TEST_CHECK(!ent.is_regular_file()); 127 TEST_CHECK(!ent.exists()); 128 } 129 permissions(dir, old_perms); 130 env.create_file("dir/file", 101); 131 { 132 directory_entry ent(sym); 133 LIBCPP_ONLY(remove(file)); 134 TEST_CHECK(ent.is_symlink()); 135 TEST_CHECK(ent.is_regular_file()); 136 TEST_CHECK(ent.exists()); 137 138 remove_if_exists(file); 139 140 std::error_code ec = GetTestEC(); 141 ent.refresh(ec); 142 TEST_CHECK(!ec); // we don't report bad symlinks as an error. 143 144 LIBCPP_ONLY(permissions(dir, perms::none)); 145 TEST_CHECK(!ent.exists()); 146 } 147 } 148 149 TEST_CASE(refresh_cannot_resolve) { 150 using namespace fs; 151 scoped_test_env env; 152 const path dir = env.create_dir("dir"); 153 const path file = env.create_file("dir/file", 42); 154 const path file_out_of_dir = env.create_file("file1", 99); 155 const path sym_out_of_dir = env.create_symlink("dir/file", "sym"); 156 const path sym_in_dir = env.create_symlink("file1", "dir/sym1"); 157 perms old_perms = status(dir).permissions(); 158 159 { 160 directory_entry ent(file); 161 permissions(dir, perms::none); 162 163 TEST_CHECK(ent.is_regular_file()); 164 165 std::error_code ec = GetTestEC(); 166 ent.refresh(ec); 167 168 TEST_CHECK(ErrorIs(ec, std::errc::permission_denied)); 169 TEST_CHECK(ent.path() == file); 170 171 ExceptionChecker Checker(file, std::errc::permission_denied, 172 "directory_entry::refresh"); 173 TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.refresh()); 174 } 175 permissions(dir, old_perms); 176 { 177 directory_entry ent(sym_in_dir); 178 permissions(dir, perms::none); 179 TEST_CHECK(ent.is_symlink()); 180 181 std::error_code ec = GetTestEC(); 182 ent.refresh(ec); 183 TEST_CHECK(ErrorIs(ec, std::errc::permission_denied)); 184 TEST_CHECK(ent.path() == sym_in_dir); 185 186 ExceptionChecker Checker(sym_in_dir, std::errc::permission_denied, 187 "directory_entry::refresh"); 188 TEST_CHECK_THROW_RESULT(filesystem_error, Checker, ent.refresh()); 189 } 190 permissions(dir, old_perms); 191 { 192 directory_entry ent(sym_out_of_dir); 193 permissions(dir, perms::none); 194 TEST_CHECK(ent.is_symlink()); 195 196 // Failure to resolve the linked entity due to permissions is not 197 // reported as an error. 198 std::error_code ec = GetTestEC(); 199 ent.refresh(ec); 200 TEST_CHECK(!ec); 201 TEST_CHECK(ent.is_symlink()); 202 203 ec = GetTestEC(); 204 TEST_CHECK(ent.exists(ec) == false); 205 TEST_CHECK(ErrorIs(ec, std::errc::permission_denied)); 206 TEST_CHECK(ent.path() == sym_out_of_dir); 207 } 208 permissions(dir, old_perms); 209 { 210 directory_entry ent_file(file); 211 directory_entry ent_sym(sym_in_dir); 212 directory_entry ent_sym2(sym_out_of_dir); 213 permissions(dir, perms::none); 214 ((void)ent_file); 215 ((void)ent_sym); 216 217 TEST_CHECK_THROW(filesystem_error, ent_file.refresh()); 218 TEST_CHECK_THROW(filesystem_error, ent_sym.refresh()); 219 TEST_CHECK_NO_THROW(ent_sym2); 220 } 221 } 222 223 TEST_CASE(refresh_doesnt_throw_on_dne_but_reports_it) { 224 using namespace fs; 225 scoped_test_env env; 226 227 const path file = env.create_file("file1", 42); 228 const path sym = env.create_symlink("file1", "sym"); 229 230 { 231 directory_entry ent(file); 232 TEST_CHECK(ent.file_size() == 42); 233 234 remove(file); 235 236 std::error_code ec = GetTestEC(); 237 ent.refresh(ec); 238 TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory)); 239 TEST_CHECK_NO_THROW(ent.refresh()); 240 241 ec = GetTestEC(); 242 TEST_CHECK(ent.file_size(ec) == uintmax_t(-1)); 243 TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory)); 244 245 // doesn't throw! 246 TEST_CHECK_THROW(filesystem_error, ent.file_size()); 247 } 248 env.create_file("file1", 99); 249 { 250 directory_entry ent(sym); 251 TEST_CHECK(ent.is_symlink()); 252 TEST_CHECK(ent.is_regular_file()); 253 TEST_CHECK(ent.file_size() == 99); 254 255 remove(file); 256 257 std::error_code ec = GetTestEC(); 258 ent.refresh(ec); 259 TEST_CHECK(!ec); 260 261 ec = GetTestEC(); 262 TEST_CHECK(ent.file_size(ec) == uintmax_t(-1)); 263 TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory)); 264 265 TEST_CHECK_THROW(filesystem_error, ent.file_size()); 266 } 267 } 268 269 TEST_CASE(access_cache_after_refresh_fails) { 270 using namespace fs; 271 scoped_test_env env; 272 const path dir = env.create_dir("dir"); 273 const path file = env.create_file("dir/file", 42); 274 const path file_out_of_dir = env.create_file("file1", 101); 275 const path sym = env.create_symlink("dir/file", "sym"); 276 const path sym_in_dir = env.create_symlink("dir/file", "dir/sym2"); 277 278 const perms old_perms = status(dir).permissions(); 279 280 #define CHECK_ACCESS(func, expect) \ 281 ec = GetTestEC(); \ 282 TEST_CHECK(ent.func(ec) == expect); \ 283 TEST_CHECK(ErrorIs(ec, std::errc::permission_denied)) 284 285 // test file doesn't exist 286 { 287 directory_entry ent(file); 288 289 TEST_CHECK(!ent.is_symlink()); 290 TEST_CHECK(ent.is_regular_file()); 291 TEST_CHECK(ent.exists()); 292 293 permissions(dir, perms::none); 294 std::error_code ec = GetTestEC(); 295 ent.refresh(ec); 296 TEST_CHECK(ErrorIs(ec, std::errc::permission_denied)); 297 298 CHECK_ACCESS(exists, false); 299 CHECK_ACCESS(is_symlink, false); 300 CHECK_ACCESS(last_write_time, file_time_type::min()); 301 CHECK_ACCESS(hard_link_count, uintmax_t(-1)); 302 } 303 permissions(dir, old_perms); 304 { 305 directory_entry ent(sym_in_dir); 306 TEST_CHECK(ent.is_symlink()); 307 TEST_CHECK(ent.is_regular_file()); 308 TEST_CHECK(ent.exists()); 309 310 permissions(dir, perms::none); 311 std::error_code ec = GetTestEC(); 312 ent.refresh(ec); 313 TEST_CHECK(ErrorIs(ec, std::errc::permission_denied)); 314 315 CHECK_ACCESS(exists, false); 316 CHECK_ACCESS(is_symlink, false); 317 CHECK_ACCESS(last_write_time, file_time_type::min()); 318 CHECK_ACCESS(hard_link_count, uintmax_t(-1)); 319 } 320 permissions(dir, old_perms); 321 { 322 directory_entry ent(sym); 323 TEST_CHECK(ent.is_symlink()); 324 TEST_CHECK(ent.is_regular_file()); 325 TEST_CHECK(ent.exists()); 326 327 permissions(dir, perms::none); 328 std::error_code ec = GetTestEC(); 329 ent.refresh(ec); 330 TEST_CHECK(!ec); 331 TEST_CHECK(ent.is_symlink()); 332 333 CHECK_ACCESS(exists, false); 334 CHECK_ACCESS(is_regular_file, false); 335 CHECK_ACCESS(last_write_time, file_time_type::min()); 336 CHECK_ACCESS(hard_link_count, uintmax_t(-1)); 337 } 338 #undef CHECK_ACCESS 339 } 340 341 TEST_SUITE_END()