libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

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()