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// bool copy_file(const path& from, const path& to); 15// bool copy_file(const path& from, const path& to, error_code& ec) noexcept; 16// bool copy_file(const path& from, const path& to, copy_options options); 17// bool copy_file(const path& from, const path& to, copy_options options, 18// error_code& ec) noexcept; 19 20#include <experimental/filesystem> 21#include <type_traits> 22#include <chrono> 23#include <cassert> 24 25#include "test_macros.h" 26#include "rapid-cxx-test.hpp" 27#include "filesystem_test_helper.hpp" 28 29using namespace std::experimental::filesystem; 30namespace fs = std::experimental::filesystem; 31 32using CO = fs::copy_options; 33 34TEST_SUITE(filesystem_copy_file_test_suite) 35 36TEST_CASE(test_signatures) 37{ 38 const path p; ((void)p); 39 const copy_options opts{}; ((void)opts); 40 std::error_code ec; ((void)ec); 41 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p)), bool); 42 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts)), bool); 43 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, ec)), bool); 44 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts, ec)), bool); 45 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p)); 46 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts)); 47 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, ec)); 48 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts, ec)); 49} 50 51TEST_CASE(test_error_reporting) 52{ 53 auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) 54 { 55#ifndef TEST_HAS_NO_EXCEPTIONS 56 try { 57 fs::copy_file(f, t); 58 return false; 59 } catch (filesystem_error const& err) { 60 return err.path1() == f 61 && err.path2() == t 62 && err.code() == ec; 63 } 64#else 65 ((void)f); ((void)t); ((void)ec); 66 return true; 67#endif 68 }; 69 70 scoped_test_env env; 71 const path file = env.create_file("file1", 42); 72 const path file2 = env.create_file("file2", 55); 73 const path non_regular_file = env.create_fifo("non_reg"); 74 const path dne = env.make_env_path("dne"); 75 { // exists(to) && equivalent(to, from) 76 std::error_code ec; 77 TEST_CHECK(fs::copy_file(file, file, copy_options::overwrite_existing, 78 ec) == false); 79 TEST_REQUIRE(ec); 80 TEST_CHECK(ec == std::make_error_code(std::errc::file_exists)); 81 TEST_CHECK(checkThrow(file, file, ec)); 82 } 83 { // exists(to) && !(skip_existing | overwrite_existing | update_existing) 84 std::error_code ec; 85 TEST_CHECK(fs::copy_file(file, file2, ec) == false); 86 TEST_REQUIRE(ec); 87 TEST_CHECK(ec == std::make_error_code(std::errc::file_exists)); 88 TEST_CHECK(checkThrow(file, file2, ec)); 89 } 90} 91 92TEST_CASE(copy_file) 93{ 94 scoped_test_env env; 95 const path file = env.create_file("file1", 42); 96 97 { // !exists(to) 98 const path dest = env.make_env_path("dest1"); 99 std::error_code ec; 100 TEST_REQUIRE(fs::copy_file(file, dest, ec) == true); 101 TEST_CHECK(!ec); 102 TEST_CHECK(file_size(dest) == 42); 103 } 104 { // exists(to) && overwrite_existing 105 const path dest = env.create_file("dest2", 55); 106 std::error_code ec; 107 TEST_REQUIRE(fs::copy_file(file, dest, 108 copy_options::overwrite_existing, ec) == true); 109 TEST_CHECK(!ec); 110 TEST_CHECK(file_size(dest) == 42); 111 } 112 { // exists(to) && update_existing 113 using Sec = std::chrono::seconds; 114 const path older = env.create_file("older_file", 1); 115 116 SleepFor(Sec(2)); 117 const path from = env.create_file("update_from", 55); 118 119 SleepFor(Sec(2)); 120 const path newer = env.create_file("newer_file", 2); 121 122 std::error_code ec; 123 TEST_REQUIRE(fs::copy_file(from, older, copy_options::update_existing, ec) == true); 124 TEST_CHECK(!ec); 125 TEST_CHECK(file_size(older) == 55); 126 127 TEST_REQUIRE(fs::copy_file(from, newer, copy_options::update_existing, ec) == false); 128 TEST_CHECK(!ec); 129 TEST_CHECK(file_size(newer) == 2); 130 } 131 { // skip_existing 132 const path file2 = env.create_file("file2", 55); 133 std::error_code ec; 134 TEST_REQUIRE(fs::copy_file(file, file2, copy_options::skip_existing, ec) == false); 135 TEST_CHECK(!ec); 136 TEST_CHECK(file_size(file2) == 55); 137 } 138} 139 140TEST_CASE(test_attributes_get_copied) 141{ 142 scoped_test_env env; 143 const path file = env.create_file("file1", 42); 144 const path dest = env.make_env_path("file2"); 145 auto st = status(file); 146 perms new_perms = perms::owner_read; 147 permissions(file, new_perms); 148 std::error_code ec; 149 TEST_REQUIRE(fs::copy_file(file, dest, ec) == true); 150 TEST_CHECK(!ec); 151 auto new_st = status(dest); 152 TEST_CHECK(new_st.permissions() == new_perms); 153} 154 155TEST_CASE(copy_dir_test) 156{ 157 scoped_test_env env; 158 const path file = env.create_file("file1", 42); 159 const path dest = env.create_dir("dir1"); 160 std::error_code ec = GetTestEC(); 161 TEST_CHECK(fs::copy_file(file, dest, ec) == false); 162 TEST_CHECK(ec); 163 TEST_CHECK(ec != GetTestEC()); 164 ec = GetTestEC(); 165 TEST_CHECK(fs::copy_file(dest, file, ec) == false); 166 TEST_CHECK(ec); 167 TEST_CHECK(ec != GetTestEC()); 168} 169 170TEST_CASE(non_regular_file_test) 171{ 172 scoped_test_env env; 173 const path fifo = env.create_fifo("fifo"); 174 const path dest = env.make_env_path("dest"); 175 const path file = env.create_file("file", 42); 176 { 177 std::error_code ec = GetTestEC(); 178 TEST_REQUIRE(fs::copy_file(fifo, dest, ec) == false); 179 TEST_CHECK(ec); 180 TEST_CHECK(ec != GetTestEC()); 181 TEST_CHECK(!exists(dest)); 182 } 183 { 184 std::error_code ec = GetTestEC(); 185 TEST_REQUIRE(fs::copy_file(file, fifo, copy_options::overwrite_existing, ec) == false); 186 TEST_CHECK(ec); 187 TEST_CHECK(ec != GetTestEC()); 188 TEST_CHECK(ec == std::make_error_code(std::errc::not_supported)); 189 TEST_CHECK(is_fifo(fifo)); 190 } 191} 192 193TEST_SUITE_END() 194