164 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// REQUIRES: can-create-symlinks10// UNSUPPORTED: c++03, c++11, c++1411// UNSUPPORTED: no-filesystem12 13// <filesystem>14 15// uintmax_t remove_all(const path& p);16// uintmax_t remove_all(const path& p, error_code& ec) noexcept;17 18#include <filesystem>19 20#include "test_macros.h"21#include "filesystem_test_helper.h"22namespace fs = std::filesystem;23using namespace fs;24 25static void test_signatures()26{27 const path p; ((void)p);28 std::error_code ec; ((void)ec);29 ASSERT_SAME_TYPE(decltype(fs::remove_all(p)), std::uintmax_t);30 ASSERT_SAME_TYPE(decltype(fs::remove_all(p, ec)), std::uintmax_t);31 32 ASSERT_NOT_NOEXCEPT(fs::remove_all(p));33 ASSERT_NOT_NOEXCEPT(fs::remove_all(p, ec));34}35 36static void test_error_reporting()37{38 scoped_test_env env;39 // Windows doesn't support setting perms::none to trigger failures40 // reading directories.41#ifndef TEST_WIN_NO_FILESYSTEM_PERMS_NONE42 auto checkThrow = [](path const& f, const std::error_code& ec)43 {44#ifndef TEST_HAS_NO_EXCEPTIONS45 try {46 fs::remove_all(f);47 return false;48 } catch (filesystem_error const& err) {49 return err.path1() == f50 && err.path2() == ""51 && err.code() == ec;52 }53#else54 ((void)f); ((void)ec);55 return true;56#endif57 };58 const path non_empty_dir = env.create_dir("dir");59 env.create_file(non_empty_dir / "file1", 42);60 const path bad_perms_dir = env.create_dir("bad_dir");61 const path file_in_bad_dir = env.create_file(bad_perms_dir / "file", 42);62 permissions(bad_perms_dir, perms::none);63 const path bad_perms_file = env.create_file("file2", 42);64 permissions(bad_perms_file, perms::none);65 66 const path testCases[] = {67 file_in_bad_dir68 };69 const auto BadRet = static_cast<std::uintmax_t>(-1);70 for (auto& p : testCases) {71 std::error_code ec;72 73 assert(fs::remove_all(p, ec) == BadRet);74 assert(ec);75 assert(checkThrow(p, ec));76 }77#endif78 79 // PR#3578080 const path testCasesNonexistant[] = {81 "",82 env.make_env_path("dne")83 };84 for (auto &p : testCasesNonexistant) {85 std::error_code ec;86 87 assert(fs::remove_all(p, ec) == 0);88 assert(!ec);89 }90}91 92static void basic_remove_all_test()93{94 scoped_test_env env;95 const path dne = env.make_env_path("dne");96 const path link = env.create_symlink(dne, "link");97 const path nested_link = env.make_env_path("nested_link");98 create_symlink(link, nested_link);99 const path testCases[] = {100 env.create_file("file", 42),101 env.create_dir("empty_dir"),102 nested_link,103 link104 };105 for (auto& p : testCases) {106 std::error_code ec = std::make_error_code(std::errc::address_in_use);107 assert(remove(p, ec));108 assert(!ec);109 assert(!exists(symlink_status(p)));110 }111}112 113static void symlink_to_dir()114{115 scoped_test_env env;116 const path dir = env.create_dir("dir");117 const path file = env.create_file(dir / "file", 42);118 const path link = env.create_directory_symlink(dir, "sym");119 120 {121 std::error_code ec = std::make_error_code(std::errc::address_in_use);122 assert(remove_all(link, ec) == 1);123 assert(!ec);124 assert(!exists(symlink_status(link)));125 assert(exists(dir));126 assert(exists(file));127 }128}129 130 131static void nested_dir()132{133 scoped_test_env env;134 const path dir = env.create_dir("dir");135 const path dir1 = env.create_dir(dir / "dir1");136 const path out_of_dir_file = env.create_file("file1", 42);137 const path all_files[] = {138 dir, dir1,139 env.create_file(dir / "file1", 42),140 env.create_symlink(out_of_dir_file, dir / "sym1"),141 env.create_file(dir1 / "file2", 42),142 env.create_directory_symlink(dir, dir1 / "sym2")143 };144 const std::size_t expected_count = sizeof(all_files) / sizeof(all_files[0]);145 146 std::error_code ec = std::make_error_code(std::errc::address_in_use);147 assert(remove_all(dir, ec) == expected_count);148 assert(!ec);149 for (auto const& p : all_files) {150 assert(!exists(symlink_status(p)));151 }152 assert(exists(out_of_dir_file));153}154 155int main(int, char**) {156 test_signatures();157 test_error_reporting();158 basic_remove_all_test();159 symlink_to_dir();160 nested_dir();161 162 return 0;163}164