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 // <filesystem> 12 13 // void rename(const path& old_p, const path& new_p); 14 // void rename(const path& old_p, const path& new_p, error_code& ec) noexcept; 15 16 #include "filesystem_include.h" 17 18 #include "test_macros.h" 19 #include "rapid-cxx-test.h" 20 #include "filesystem_test_helper.h" 21 22 using namespace fs; 23 24 TEST_SUITE(filesystem_rename_test_suite) 25 26 TEST_CASE(test_signatures) 27 { 28 const path p; ((void)p); 29 std::error_code ec; ((void)ec); 30 ASSERT_SAME_TYPE(decltype(fs::rename(p, p)), void); 31 ASSERT_SAME_TYPE(decltype(fs::rename(p, p, ec)), void); 32 33 ASSERT_NOT_NOEXCEPT(fs::rename(p, p)); 34 ASSERT_NOEXCEPT(fs::rename(p, p, ec)); 35 } 36 37 TEST_CASE(test_error_reporting) 38 { 39 auto checkThrow = [](path const& f, path const& t, const std::error_code& ec) 40 { 41 #ifndef TEST_HAS_NO_EXCEPTIONS 42 try { 43 fs::rename(f, t); 44 return false; 45 } catch (filesystem_error const& err) { 46 return err.path1() == f 47 && err.path2() == t 48 && err.code() == ec; 49 } 50 #else 51 ((void)f); ((void)t); ((void)ec); 52 return true; 53 #endif 54 }; 55 scoped_test_env env; 56 const path dne = env.make_env_path("dne"); 57 const path file = env.create_file("file1", 42); 58 const path dir = env.create_dir("dir1"); 59 struct TestCase { 60 path from; 61 path to; 62 } cases[] = { 63 {dne, dne}, 64 {file, dir}, 65 {dir, file} 66 }; 67 for (auto& TC : cases) { 68 auto from_before = status(TC.from); 69 auto to_before = status(TC.to); 70 std::error_code ec; 71 rename(TC.from, TC.to, ec); 72 TEST_REQUIRE(ec); 73 TEST_CHECK(from_before.type() == status(TC.from).type()); 74 TEST_CHECK(to_before.type() == status(TC.to).type()); 75 TEST_CHECK(checkThrow(TC.from, TC.to, ec)); 76 } 77 } 78 79 TEST_CASE(basic_rename_test) 80 { 81 scoped_test_env env; 82 83 const std::error_code set_ec = std::make_error_code(std::errc::address_in_use); 84 const path file = env.create_file("file1", 42); 85 { // same file 86 std::error_code ec = set_ec; 87 rename(file, file, ec); 88 TEST_CHECK(!ec); 89 TEST_CHECK(is_regular_file(file)); 90 TEST_CHECK(file_size(file) == 42); 91 } 92 const path sym = env.create_symlink(file, "sym"); 93 { // file -> symlink 94 std::error_code ec = set_ec; 95 rename(file, sym, ec); 96 TEST_CHECK(!ec); 97 TEST_CHECK(!exists(file)); 98 TEST_CHECK(is_regular_file(symlink_status(sym))); 99 TEST_CHECK(file_size(sym) == 42); 100 } 101 const path file2 = env.create_file("file2", 42); 102 const path file3 = env.create_file("file3", 100); 103 { // file -> file 104 std::error_code ec = set_ec; 105 rename(file2, file3, ec); 106 TEST_CHECK(!ec); 107 TEST_CHECK(!exists(file2)); 108 TEST_CHECK(is_regular_file(file3)); 109 TEST_CHECK(file_size(file3) == 42); 110 } 111 const path dne = env.make_env_path("dne"); 112 const path bad_sym = env.create_symlink(dne, "bad_sym"); 113 const path bad_sym_dest = env.make_env_path("bad_sym2"); 114 { // bad-symlink 115 std::error_code ec = set_ec; 116 rename(bad_sym, bad_sym_dest, ec); 117 TEST_CHECK(!ec); 118 TEST_CHECK(!exists(symlink_status(bad_sym))); 119 TEST_CHECK(is_symlink(bad_sym_dest)); 120 TEST_CHECK(read_symlink(bad_sym_dest) == dne); 121 } 122 } 123 124 TEST_SUITE_END() 125