diff options
Diffstat (limited to 'libstdc++-v3/testsuite/experimental/filesystem')
-rw-r--r-- | libstdc++-v3/testsuite/experimental/filesystem/operations/rename.cc | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/rename.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/rename.cc new file mode 100644 index 0000000..56039e7 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/rename.cc @@ -0,0 +1,180 @@ +// Copyright (C) 2021 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-DUSE_FILESYSTEM_TS -lstdc++fs" } +// { dg-do run { target c++11 } } +// { dg-require-filesystem-ts "" } + +#include <experimental/filesystem> +#include <testsuite_hooks.h> +#include <testsuite_fs.h> + +namespace fs = std::experimental::filesystem; + +void +test01() +{ + std::error_code ec; + const std::error_code bad_ec = make_error_code(std::errc::invalid_argument); + + auto p1 = __gnu_test::nonexistent_path(); + auto p2 = __gnu_test::nonexistent_path(); + + fs::rename(p1, p2, ec); + VERIFY( ec ); + + ec.clear(); + fs::rename(p1, "", ec); + VERIFY( ec ); + + ec.clear(); + fs::rename("", p1, ec); + VERIFY( ec ); + + ec = bad_ec; + std::ofstream{p1}; // create file + fs::rename(p1, p1, ec); // no-op + VERIFY( !ec ); + VERIFY( is_regular_file(p1) ); + + ec.clear(); + rename(p2, p1, ec); + VERIFY( ec ); + VERIFY( is_regular_file(p1) ); + + ec = bad_ec; + fs::rename(p1, p2, ec); + VERIFY( !ec ); + VERIFY( !exists(p1) ); + VERIFY( is_regular_file(p2) ); + + ec = bad_ec; + std::ofstream{p1}; // create file + fs::rename(p1, p2, ec); + VERIFY( !ec ); + VERIFY( !exists(p1) ); + VERIFY( is_regular_file(p2) ); + + fs::remove(p2, ec); +} + +void +test_symlinks() +{ +#if defined(__MINGW32__) || defined(__MINGW64__) + // No symlink support +#else + std::error_code ec; + const std::error_code bad_ec = make_error_code(std::errc::invalid_argument); + + const auto dir = __gnu_test::nonexistent_path(); + fs::create_directory(dir); + + create_symlink(dir/"nonesuch", dir/"link"); // dangling symlink + ec = bad_ec; + fs::rename(dir/"link", dir/"newlink", ec); + VERIFY( !ec ); + VERIFY( !exists(symlink_status(dir/"link")) ); + VERIFY( is_symlink(dir/"newlink") ); + + __gnu_test::scoped_file f(dir/"file"); + create_symlink(dir/"file", dir/"link"); + ec = bad_ec; + fs::rename(dir/"link", dir/"newerlink", ec); + VERIFY( !ec ); + VERIFY( !exists(symlink_status(dir/"link")) ); + VERIFY( is_symlink(dir/"newerlink") ); + VERIFY( is_regular_file(dir/"file") ); + + fs::remove_all(dir, ec); + f.path.clear(); +#endif +} + +void +test_directories() +{ + std::error_code ec; + const std::error_code bad_ec = make_error_code(std::errc::invalid_argument); + + const auto dir = __gnu_test::nonexistent_path(); + fs::create_directory(dir); + __gnu_test::scoped_file f(dir/"file"); + fs::create_directory(dir/"subdir"); + + // Rename directory. + ec = bad_ec; + fs::rename(dir/"subdir", dir/"subdir2", ec); + VERIFY( !ec ); + VERIFY( is_directory(dir/"subdir2") ); + VERIFY( !exists(dir/"subdir") ); + + // Cannot rename a directory to a sub-directory of itself. + fs::rename(dir/"subdir2", dir/"subdir2/subsubdir", ec); + VERIFY( ec ); + VERIFY( is_directory(dir/"subdir2") ); + VERIFY( !exists(dir/"subdir2"/"subsubdir") ); + + // Cannot rename a file to the name of an existing directory. + ec.clear(); + fs::rename(dir/"file", dir/"subdir2", ec); + VERIFY( ec ); + VERIFY( is_directory(dir/"subdir2") ); + VERIFY( is_regular_file(dir/"file") ); + +#if defined(__MINGW32__) || defined(__MINGW64__) + // XXX broken on Windows, see PR 98985 +#else + // Cannot rename a directory to the name of an existing non-directory + ec.clear(); + fs::rename(dir/"subdir2", dir/"file", ec); + VERIFY( ec ); + VERIFY( is_regular_file(dir/"file") ); + VERIFY( is_directory(dir/"subdir2") ); + + // Cannot rename directory to the name of a non-empty directory. + ec.clear(); + __gnu_test::scoped_file f2(dir/"subdir2/file"); + fs::create_directory(dir/"subdir"); + fs::rename(dir/"subdir", dir/"subdir2", ec); + VERIFY( ec ); + VERIFY( is_directory(dir/"subdir") ); + VERIFY( is_directory(dir/"subdir2") ); + VERIFY( is_regular_file(dir/"subdir2/file") ); + + // Can rename a non-empty directory to the name of an empty directory. + ec = bad_ec; + fs::rename(dir/"subdir2", dir/"subdir", ec); + VERIFY( !ec ); + VERIFY( is_directory(dir/"subdir") ); + VERIFY( !exists(dir/"subdir2") ); + VERIFY( is_regular_file(dir/"subdir/file") ); + f2.path.clear(); + + f.path.clear(); +#endif + + fs::remove_all(dir, ec); +} + +int +main() +{ + test01(); + test_symlinks(); + test_directories(); +} |