brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · d86c91d Raw
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// void rename(const path& old_p, const path& new_p);16// void rename(const path& old_p,  const path& new_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::rename(p, p)), void);30    ASSERT_SAME_TYPE(decltype(fs::rename(p, p, ec)), void);31 32    ASSERT_NOT_NOEXCEPT(fs::rename(p, p));33    ASSERT_NOEXCEPT(fs::rename(p, p, ec));34}35 36static void test_error_reporting()37{38    auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)39    {40#ifndef TEST_HAS_NO_EXCEPTIONS41        try {42            fs::rename(f, t);43            return false;44        } catch (filesystem_error const& err) {45            return err.path1() == f46                && err.path2() == t47                && err.code() == ec;48        }49#else50        ((void)f); ((void)t); ((void)ec);51        return true;52#endif53    };54    scoped_test_env env;55    const path dne = env.make_env_path("dne");56    const path file = env.create_file("file1", 42);57    const path dir = env.create_dir("dir1");58    struct TestCase {59      path from;60      path to;61    } cases[] = {62        {dne, dne},63        {file, dir},64#ifndef _WIN3265        // The spec doesn't say that this case must be an error; fs.op.rename66        // note 1.2.1 says that a file may be overwritten by a rename.67        // On Windows, with rename() implemented with MoveFileExW, overwriting68        // a file with a directory is not an error.69        {dir, file},70#endif71    };72    for (auto& TC : cases) {73        auto from_before = status(TC.from);74        auto to_before = status(TC.to);75        std::error_code ec;76        rename(TC.from, TC.to, ec);77        assert(ec);78        assert(from_before.type() == status(TC.from).type());79        assert(to_before.type() == status(TC.to).type());80        assert(checkThrow(TC.from, TC.to, ec));81    }82}83 84static void basic_rename_test()85{86    scoped_test_env env;87 88    const std::error_code set_ec = std::make_error_code(std::errc::address_in_use);89    const path file = env.create_file("file1", 42);90    { // same file91        std::error_code ec = set_ec;92        rename(file, file, ec);93        assert(!ec);94        assert(is_regular_file(file));95        assert(file_size(file) == 42);96    }97    const path sym = env.create_symlink(file, "sym");98    { // file -> symlink99        std::error_code ec = set_ec;100        rename(file, sym, ec);101        assert(!ec);102        assert(!exists(file));103        assert(is_regular_file(symlink_status(sym)));104        assert(file_size(sym) == 42);105    }106    const path file2 = env.create_file("file2", 42);107    const path file3 = env.create_file("file3", 100);108    { // file -> file109        std::error_code ec = set_ec;110        rename(file2, file3, ec);111        assert(!ec);112        assert(!exists(file2));113        assert(is_regular_file(file3));114        assert(file_size(file3) == 42);115    }116    const path dne = env.make_env_path("dne");117    const path bad_sym = env.create_symlink(dne, "bad_sym");118    const path bad_sym_dest = env.make_env_path("bad_sym2");119    { // bad-symlink120        std::error_code ec = set_ec;121        rename(bad_sym, bad_sym_dest, ec);122        assert(!ec);123        assert(!exists(symlink_status(bad_sym)));124        assert(is_symlink(bad_sym_dest));125        assert(read_symlink(bad_sym_dest) == dne);126    }127}128 129static void basic_rename_dir_test()130{131    static_test_env env;132    const std::error_code set_ec = std::make_error_code(std::errc::address_in_use);133    const path new_dir = env.makePath("new_dir");134    { // dir -> dir (with contents)135        std::error_code ec = set_ec;136        rename(env.Dir, new_dir, ec);137        assert(!ec);138        assert(!exists(env.Dir));139        assert(is_directory(new_dir));140        assert(exists(new_dir / "file1"));141    }142#ifdef _WIN32143    // On Windows, renaming a directory over a file isn't an error (this144    // case is skipped in test_error_reporting above).145    { // dir -> file146        std::error_code ec = set_ec;147        rename(new_dir, env.NonEmptyFile, ec);148        assert(!ec);149        assert(!exists(new_dir));150        assert(is_directory(env.NonEmptyFile));151        assert(exists(env.NonEmptyFile / "file1"));152    }153#endif154}155 156int main(int, char**) {157    test_signatures();158    test_error_reporting();159    basic_rename_test();160    basic_rename_dir_test();161 162    return 0;163}164