1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03 10 // UNSUPPORTED: no-filesystem 11 // UNSUPPORTED: availability-filesystem-missing 12 13 // The string reported on errors changed, which makes those tests fail when run 14 // against already-released libc++'s. 15 // XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx{{10.15|11.0}} 16 17 // <filesystem> 18 19 // bool copy_file(const path& from, const path& to); 20 // bool copy_file(const path& from, const path& to, error_code& ec) noexcept; 21 // bool copy_file(const path& from, const path& to, copy_options options); 22 // bool copy_file(const path& from, const path& to, copy_options options, 23 // error_code& ec) noexcept; 24 25 #include "filesystem_include.h" 26 #include <type_traits> 27 #include <chrono> 28 #include <cassert> 29 30 #include "assert_macros.h" 31 #include "test_macros.h" 32 #include "filesystem_test_helper.h" 33 34 using namespace fs; 35 36 using CO = fs::copy_options; 37 38 static void test_signatures() { 39 const path p; 40 ((void)p); 41 const copy_options opts{}; 42 ((void)opts); 43 std::error_code ec; 44 ((void)ec); 45 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p)), bool); 46 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts)), bool); 47 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, ec)), bool); 48 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts, ec)), bool); 49 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p)); 50 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts)); 51 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, ec)); 52 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts, ec)); 53 } 54 55 static void test_error_reporting() { 56 57 scoped_test_env env; 58 const path file = env.create_file("file1", 42); 59 const path file2 = env.create_file("file2", 55); 60 61 { // exists(to) && equivalent(to, from) 62 std::error_code ec; 63 assert(fs::copy_file(file, file, copy_options::overwrite_existing, 64 ec) == false); 65 assert(ErrorIs(ec, std::errc::file_exists)); 66 ExceptionChecker Checker(file, file, std::errc::file_exists, "copy_file"); 67 TEST_VALIDATE_EXCEPTION(filesystem_error, Checker, copy_file(file, file, copy_options::overwrite_existing)); 68 69 } 70 { // exists(to) && !(skip_existing | overwrite_existing | update_existing) 71 std::error_code ec; 72 assert(fs::copy_file(file, file2, ec) == false); 73 assert(ErrorIs(ec, std::errc::file_exists)); 74 ExceptionChecker Checker(file, file, std::errc::file_exists, "copy_file"); 75 TEST_VALIDATE_EXCEPTION(filesystem_error, Checker, copy_file(file, file, copy_options::overwrite_existing)); 76 77 } 78 } 79 80 #ifndef _WIN32 81 static void non_regular_file_test() { 82 scoped_test_env env; 83 const path fifo = env.create_fifo("fifo"); 84 const path dest = env.make_env_path("dest"); 85 const path file = env.create_file("file", 42); 86 87 { 88 std::error_code ec = GetTestEC(); 89 assert(fs::copy_file(fifo, dest, ec) == false); 90 assert(ErrorIs(ec, std::errc::not_supported)); 91 assert(!exists(dest)); 92 } 93 { 94 std::error_code ec = GetTestEC(); 95 assert(fs::copy_file(file, fifo, copy_options::overwrite_existing, 96 ec) == false); 97 assert(ErrorIs(ec, std::errc::not_supported)); 98 assert(is_fifo(fifo)); 99 } 100 101 } 102 #endif // _WIN32 103 104 static void test_attributes_get_copied() { 105 scoped_test_env env; 106 const path file = env.create_file("file1", 42); 107 const path dest = env.make_env_path("file2"); 108 (void)status(file); 109 perms new_perms = perms::owner_read; 110 permissions(file, new_perms); 111 std::error_code ec = GetTestEC(); 112 assert(fs::copy_file(file, dest, ec) == true); 113 assert(!ec); 114 auto new_st = status(dest); 115 assert(new_st.permissions() == NormalizeExpectedPerms(new_perms)); 116 } 117 118 static void copy_dir_test() { 119 scoped_test_env env; 120 const path file = env.create_file("file1", 42); 121 const path dest = env.create_dir("dir1"); 122 std::error_code ec = GetTestEC(); 123 assert(fs::copy_file(file, dest, ec) == false); 124 assert(ec); 125 assert(ec != GetTestEC()); 126 ec = GetTestEC(); 127 assert(fs::copy_file(dest, file, ec) == false); 128 assert(ec); 129 assert(ec != GetTestEC()); 130 } 131 132 static void copy_file() { 133 scoped_test_env env; 134 const path file = env.create_file("file1", 42); 135 136 { // !exists(to) 137 const path dest = env.make_env_path("dest1"); 138 std::error_code ec = GetTestEC(); 139 140 assert(fs::copy_file(file, dest, ec) == true); 141 assert(!ec); 142 assert(file_size(dest) == 42); 143 } 144 { // exists(to) && overwrite_existing 145 const path dest = env.create_file("dest2", 55); 146 permissions(dest, perms::all); 147 permissions(file, 148 perms::group_write | perms::owner_write | perms::others_write, 149 perm_options::remove); 150 151 std::error_code ec = GetTestEC(); 152 assert(fs::copy_file(file, dest, copy_options::overwrite_existing, 153 ec) == true); 154 assert(!ec); 155 assert(file_size(dest) == 42); 156 assert(status(dest).permissions() == status(file).permissions()); 157 } 158 { // exists(to) && update_existing 159 using Sec = std::chrono::seconds; 160 const path older = env.create_file("older_file", 1); 161 162 SleepFor(Sec(2)); 163 const path from = env.create_file("update_from", 55); 164 165 SleepFor(Sec(2)); 166 const path newer = env.create_file("newer_file", 2); 167 168 std::error_code ec = GetTestEC(); 169 assert( 170 fs::copy_file(from, older, copy_options::update_existing, ec) == true); 171 assert(!ec); 172 assert(file_size(older) == 55); 173 174 assert( 175 fs::copy_file(from, newer, copy_options::update_existing, ec) == false); 176 assert(!ec); 177 assert(file_size(newer) == 2); 178 } 179 { // skip_existing 180 const path file2 = env.create_file("file2", 55); 181 std::error_code ec = GetTestEC(); 182 assert(fs::copy_file(file, file2, copy_options::skip_existing, ec) == 183 false); 184 assert(!ec); 185 assert(file_size(file2) == 55); 186 } 187 } 188 189 int main(int, char**) { 190 test_signatures(); 191 test_error_reporting(); 192 #ifndef _WIN32 193 non_regular_file_test(); 194 #endif 195 test_attributes_get_copied(); 196 copy_dir_test(); 197 copy_file(); 198 199 return 0; 200 } 201