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 11 // The string reported on errors changed, which makes those tests fail when run 12 // against already-released libc++'s. 13 // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.15 14 15 // <filesystem> 16 17 // bool copy_file(const path& from, const path& to); 18 // bool copy_file(const path& from, const path& to, error_code& ec) noexcept; 19 // bool copy_file(const path& from, const path& to, copy_options options); 20 // bool copy_file(const path& from, const path& to, copy_options options, 21 // error_code& ec) noexcept; 22 23 #include "filesystem_include.h" 24 #include <type_traits> 25 #include <chrono> 26 #include <cassert> 27 28 #include "test_macros.h" 29 #include "rapid-cxx-test.h" 30 #include "filesystem_test_helper.h" 31 32 using namespace fs; 33 34 using CO = fs::copy_options; 35 36 TEST_SUITE(filesystem_copy_file_test_suite) 37 38 TEST_CASE(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 TEST_CASE(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 TEST_CHECK(fs::copy_file(file, file, copy_options::overwrite_existing, 64 ec) == false); 65 TEST_CHECK(ErrorIs(ec, std::errc::file_exists)); 66 ExceptionChecker Checker(file, file, std::errc::file_exists, "copy_file"); 67 TEST_CHECK_THROW_RESULT(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 TEST_CHECK(fs::copy_file(file, file2, ec) == false); 73 TEST_CHECK(ErrorIs(ec, std::errc::file_exists)); 74 ExceptionChecker Checker(file, file, std::errc::file_exists, "copy_file"); 75 TEST_CHECK_THROW_RESULT(filesystem_error, Checker, copy_file(file, file, copy_options::overwrite_existing)); 76 77 } 78 } 79 80 #ifndef _WIN32 81 TEST_CASE(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 TEST_REQUIRE(fs::copy_file(fifo, dest, ec) == false); 90 TEST_CHECK(ErrorIs(ec, std::errc::not_supported)); 91 TEST_CHECK(!exists(dest)); 92 } 93 { 94 std::error_code ec = GetTestEC(); 95 TEST_REQUIRE(fs::copy_file(file, fifo, copy_options::overwrite_existing, 96 ec) == false); 97 TEST_CHECK(ErrorIs(ec, std::errc::not_supported)); 98 TEST_CHECK(is_fifo(fifo)); 99 } 100 101 } 102 #endif 103 104 TEST_CASE(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 TEST_REQUIRE(fs::copy_file(file, dest, ec) == true); 113 TEST_CHECK(!ec); 114 auto new_st = status(dest); 115 TEST_CHECK(new_st.permissions() == NormalizeExpectedPerms(new_perms)); 116 } 117 118 TEST_CASE(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 TEST_CHECK(fs::copy_file(file, dest, ec) == false); 124 TEST_CHECK(ec); 125 TEST_CHECK(ec != GetTestEC()); 126 ec = GetTestEC(); 127 TEST_CHECK(fs::copy_file(dest, file, ec) == false); 128 TEST_CHECK(ec); 129 TEST_CHECK(ec != GetTestEC()); 130 } 131 132 TEST_CASE(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 TEST_REQUIRE(fs::copy_file(file, dest, ec) == true); 141 TEST_CHECK(!ec); 142 TEST_CHECK(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 TEST_REQUIRE(fs::copy_file(file, dest, copy_options::overwrite_existing, 153 ec) == true); 154 TEST_CHECK(!ec); 155 TEST_CHECK(file_size(dest) == 42); 156 TEST_CHECK(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 TEST_REQUIRE( 170 fs::copy_file(from, older, copy_options::update_existing, ec) == true); 171 TEST_CHECK(!ec); 172 TEST_CHECK(file_size(older) == 55); 173 174 TEST_REQUIRE( 175 fs::copy_file(from, newer, copy_options::update_existing, ec) == false); 176 TEST_CHECK(!ec); 177 TEST_CHECK(file_size(newer) == 2); 178 } 179 { // skip_existing 180 const path file2 = env.create_file("file2", 55); 181 std::error_code ec = GetTestEC(); 182 TEST_REQUIRE(fs::copy_file(file, file2, copy_options::skip_existing, ec) == 183 false); 184 TEST_CHECK(!ec); 185 TEST_CHECK(file_size(file2) == 55); 186 } 187 } 188 189 190 TEST_SUITE_END() 191