203 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410// UNSUPPORTED: no-filesystem11 12// The string reported on errors changed, which makes those tests fail when run13// against a built library that doesn't contain 0aa637b2037d.14// XFAIL: using-built-library-before-llvm-1315 16// Starting in Android N (API 24), SELinux policy prevents the shell user from17// creating a FIFO file.18// XFAIL: LIBCXX-ANDROID-FIXME && !android-device-api={{21|22|23}}19 20// <filesystem>21 22// bool copy_file(const path& from, const path& to);23// bool copy_file(const path& from, const path& to, error_code& ec) noexcept;24// bool copy_file(const path& from, const path& to, copy_options options);25// bool copy_file(const path& from, const path& to, copy_options options, error_code& ec) noexcept;26 27#include <filesystem>28#include <type_traits>29#include <chrono>30#include <cassert>31 32#include "assert_macros.h"33#include "test_macros.h"34#include "filesystem_test_helper.h"35namespace fs = std::filesystem;36using namespace fs;37 38using CO = fs::copy_options;39 40static void test_signatures() {41 const path p;42 ((void)p);43 const copy_options opts{};44 ((void)opts);45 std::error_code ec;46 ((void)ec);47 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p)), bool);48 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts)), bool);49 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, ec)), bool);50 ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts, ec)), bool);51 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p));52 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts));53 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, ec));54 ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts, ec));55}56 57static void test_error_reporting() {58 59 scoped_test_env env;60 const path file = env.create_file("file1", 42);61 const path file2 = env.create_file("file2", 55);62 63 { // exists(to) && equivalent(to, from)64 std::error_code ec;65 assert(fs::copy_file(file, file, copy_options::overwrite_existing,66 ec) == false);67 assert(ErrorIs(ec, std::errc::file_exists));68 ExceptionChecker Checker(file, file, std::errc::file_exists, "copy_file");69 TEST_VALIDATE_EXCEPTION(filesystem_error, Checker, copy_file(file, file, copy_options::overwrite_existing));70 71 }72 { // exists(to) && !(skip_existing | overwrite_existing | update_existing)73 std::error_code ec;74 assert(fs::copy_file(file, file2, ec) == false);75 assert(ErrorIs(ec, std::errc::file_exists));76 ExceptionChecker Checker(file, file, std::errc::file_exists, "copy_file");77 TEST_VALIDATE_EXCEPTION(filesystem_error, Checker, copy_file(file, file, copy_options::overwrite_existing));78 79 }80}81 82#ifndef _WIN3283static void non_regular_file_test() {84 scoped_test_env env;85 const path fifo = env.create_fifo("fifo");86 const path dest = env.make_env_path("dest");87 const path file = env.create_file("file", 42);88 89 {90 std::error_code ec = GetTestEC();91 assert(fs::copy_file(fifo, dest, ec) == false);92 assert(ErrorIs(ec, std::errc::not_supported));93 assert(!exists(dest));94 }95 {96 std::error_code ec = GetTestEC();97 assert(fs::copy_file(file, fifo, copy_options::overwrite_existing,98 ec) == false);99 assert(ErrorIs(ec, std::errc::not_supported));100 assert(is_fifo(fifo));101 }102 103}104#endif // _WIN32105 106static void test_attributes_get_copied() {107 scoped_test_env env;108 const path file = env.create_file("file1", 42);109 const path dest = env.make_env_path("file2");110 (void)status(file);111 perms new_perms = perms::owner_read;112 permissions(file, new_perms);113 std::error_code ec = GetTestEC();114 assert(fs::copy_file(file, dest, ec) == true);115 assert(!ec);116 auto new_st = status(dest);117 assert(new_st.permissions() == NormalizeExpectedPerms(new_perms));118}119 120static void copy_dir_test() {121 scoped_test_env env;122 const path file = env.create_file("file1", 42);123 const path dest = env.create_dir("dir1");124 std::error_code ec = GetTestEC();125 assert(fs::copy_file(file, dest, ec) == false);126 assert(ec);127 assert(ec != GetTestEC());128 ec = GetTestEC();129 assert(fs::copy_file(dest, file, ec) == false);130 assert(ec);131 assert(ec != GetTestEC());132}133 134static void copy_file() {135 scoped_test_env env;136 const path file = env.create_file("file1", 42);137 138 { // !exists(to)139 const path dest = env.make_env_path("dest1");140 std::error_code ec = GetTestEC();141 142 assert(fs::copy_file(file, dest, ec) == true);143 assert(!ec);144 assert(file_size(dest) == 42);145 }146 { // exists(to) && overwrite_existing147 const path dest = env.create_file("dest2", 55);148 permissions(dest, perms::all);149 permissions(file,150 perms::group_write | perms::owner_write | perms::others_write,151 perm_options::remove);152 153 std::error_code ec = GetTestEC();154 assert(fs::copy_file(file, dest, copy_options::overwrite_existing,155 ec) == true);156 assert(!ec);157 assert(file_size(dest) == 42);158 assert(status(dest).permissions() == status(file).permissions());159 }160 { // exists(to) && update_existing161 using Sec = std::chrono::seconds;162 const path older = env.create_file("older_file", 1);163 164 SleepFor(Sec(2));165 const path from = env.create_file("update_from", 55);166 167 SleepFor(Sec(2));168 const path newer = env.create_file("newer_file", 2);169 170 std::error_code ec = GetTestEC();171 assert(172 fs::copy_file(from, older, copy_options::update_existing, ec) == true);173 assert(!ec);174 assert(file_size(older) == 55);175 176 assert(177 fs::copy_file(from, newer, copy_options::update_existing, ec) == false);178 assert(!ec);179 assert(file_size(newer) == 2);180 }181 { // skip_existing182 const path file2 = env.create_file("file2", 55);183 std::error_code ec = GetTestEC();184 assert(fs::copy_file(file, file2, copy_options::skip_existing, ec) ==185 false);186 assert(!ec);187 assert(file_size(file2) == 55);188 }189}190 191int main(int, char**) {192 test_signatures();193 test_error_reporting();194#ifndef _WIN32195 non_regular_file_test();196#endif197 test_attributes_get_copied();198 copy_dir_test();199 copy_file();200 201 return 0;202}203