summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/experimental/filesystem/fs.op.funcs
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2016-06-17 19:46:40 +0000
committerEric Fiselier <eric@efcs.ca>2016-06-17 19:46:40 +0000
commitc79795874adef276115f8bcf0b46da4155d2d46d (patch)
tree3c58305df7b6b28f1626e65f704ca3aba480be3a /libcxx/test/std/experimental/filesystem/fs.op.funcs
parent7a5813597dad665e4461372edbc3a6ea8e8cb8f0 (diff)
downloadbcm5719-llvm-c79795874adef276115f8bcf0b46da4155d2d46d.tar.gz
bcm5719-llvm-c79795874adef276115f8bcf0b46da4155d2d46d.zip
Add Filesystem TS -- Complete
Add the completed std::experimental::filesystem implementation and tests. The implementation supports C++11 or newer. The TS is built as part of 'libc++experimental.a'. Users of the TS need to manually link this library. Building and testing the TS can be disabled using the CMake option '-DLIBCXX_ENABLE_FILESYSTEM=OFF'. Currently 'libc++experimental.a' is not installed by default. To turn on the installation of the library use '-DLIBCXX_INSTALL_EXPERIMENTAL_LIBRARY=ON'. llvm-svn: 273034
Diffstat (limited to 'libcxx/test/std/experimental/filesystem/fs.op.funcs')
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp117
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp118
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp251
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp165
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp110
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp72
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp104
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp103
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp81
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp90
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp92
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp93
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp88
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp84
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp79
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp86
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp84
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp84
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp91
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp80
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp84
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp84
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp87
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp84
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp105
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp297
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp154
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp100
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp97
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp141
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp125
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp109
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp113
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp159
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp59
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp192
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp58
-rw-r--r--libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp110
38 files changed, 4230 insertions, 0 deletions
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp
new file mode 100644
index 00000000000..4d59235c722
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.absolute/absolute.pass.cpp
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// path absolute(const path& p, const path& base=current_path());
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(filesystem_absolute_path_test_suite)
+
+TEST_CASE(absolute_signature_test)
+{
+ const path p; ((void)p);
+ ASSERT_NOT_NOEXCEPT(absolute(p));
+ ASSERT_NOT_NOEXCEPT(absolute(p, p));
+}
+
+// There are 4 cases is the proposal for absolute path.
+// Each scope tests one of the cases.
+TEST_CASE(absolute_path_test)
+{
+ // has_root_name() && has_root_directory()
+ {
+ const path p("//net/foo");
+ const path base("//net/bar/baz");
+ TEST_REQUIRE(p.has_root_name());
+ TEST_REQUIRE(p.has_root_directory());
+ TEST_CHECK(p.is_absolute());
+ path ret = absolute(p, base);
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(ret == p);
+ }
+ // !has_root_name() && has_root_directory()
+ {
+ const path p("/foo");
+ const path base("//net/bar");
+ TEST_REQUIRE(not p.has_root_name());
+ TEST_REQUIRE(p.has_root_directory());
+ TEST_CHECK(p.is_absolute());
+ // ensure absolute(base) is not recursivly called
+ TEST_REQUIRE(base.has_root_name());
+ TEST_REQUIRE(base.has_root_directory());
+
+ path ret = absolute(p, base);
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(ret.has_root_name());
+ TEST_CHECK(ret.root_name() == path("//net"));
+ TEST_CHECK(ret.has_root_directory());
+ TEST_CHECK(ret.root_directory() == path("/"));
+ TEST_CHECK(ret == path("//net/foo"));
+ }
+ // has_root_name() && !has_root_directory()
+ {
+ const path p("//net");
+ const path base("//net/foo/bar");
+ TEST_REQUIRE(p.has_root_name());
+ TEST_REQUIRE(not p.has_root_directory());
+ TEST_CHECK(not p.is_absolute());
+ // absolute is called recursivly on base. The following conditions
+ // must be true for it to return base unmodified
+ TEST_REQUIRE(base.has_root_name());
+ TEST_REQUIRE(base.has_root_directory());
+ path ret = absolute(p, base);
+ const path expect("//net/foo/bar");
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(ret == path("//net/foo/bar"));
+ }
+ // !has_root_name() && !has_root_directory()
+ {
+ const path p("bar/baz");
+ const path base("//net/foo");
+ TEST_REQUIRE(not p.has_root_name());
+ TEST_REQUIRE(not p.has_root_directory());
+ TEST_REQUIRE(base.has_root_name());
+ TEST_REQUIRE(base.has_root_directory());
+
+ path ret = absolute(p, base);
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(ret == path("//net/foo/bar/baz"));
+ }
+}
+
+TEST_CASE(absolute_path_with_default_base)
+{
+ const path testCases[] = {
+ "//net/foo", // has_root_name() && has_root_directory()
+ "/foo", // !has_root_name() && has_root_directory()
+ "//net", // has_root_name() && !has_root_directory()
+ "bar/baz" // !has_root_name() && !has_root_directory()
+ };
+ const path base = current_path();
+ for (auto& p : testCases) {
+ const path ret = absolute(p);
+ const path expect = absolute(p, base);
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(ret == expect);
+ }
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
new file mode 100644
index 00000000000..6b114d0e40a
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// path canonical(const path& p, const path& base = current_path());
+// path canonical(const path& p, error_code& ec);
+// path canonical(const path& p, const path& base, error_code& ec);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(filesystem_canonical_path_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(canonical(p));
+ ASSERT_NOT_NOEXCEPT(canonical(p, p));
+ ASSERT_NOT_NOEXCEPT(canonical(p, ec));
+ ASSERT_NOT_NOEXCEPT(canonical(p, p, ec));
+}
+
+// There are 4 cases is the proposal for absolute path.
+// Each scope tests one of the cases.
+TEST_CASE(test_canonical)
+{
+ // has_root_name() && has_root_directory()
+ const path Root = StaticEnv::Root;
+ const path RootName = Root.filename();
+ const path DirName = StaticEnv::Dir.filename();
+ const path SymlinkName = StaticEnv::SymlinkToFile.filename();
+ struct TestCase {
+ path p;
+ path expect;
+ path base = StaticEnv::Root;
+ };
+ const TestCase testCases[] = {
+ { ".", Root, Root},
+ { DirName / ".." / "." / DirName, StaticEnv::Dir, Root},
+ { StaticEnv::Dir2 / "..", StaticEnv::Dir },
+ { StaticEnv::Dir3 / "../..", StaticEnv::Dir },
+ { StaticEnv::Dir / ".", StaticEnv::Dir },
+ { Root / "." / DirName / ".." / DirName, StaticEnv::Dir},
+ { path("..") / "." / RootName / DirName / ".." / DirName, StaticEnv::Dir, Root},
+ { StaticEnv::SymlinkToFile, StaticEnv::File },
+ { SymlinkName, StaticEnv::File, StaticEnv::Root}
+ };
+ for (auto& TC : testCases) {
+ std::error_code ec;
+ const path ret = canonical(TC.p, TC.base, ec);
+ TEST_REQUIRE(!ec);
+ const path ret2 = canonical(TC.p, TC.base);
+ TEST_CHECK(ret == TC.expect);
+ TEST_CHECK(ret == ret2);
+ TEST_CHECK(ret.is_absolute());
+ }
+}
+
+TEST_CASE(test_dne_path)
+{
+ std::error_code ec;
+ {
+ const path ret = canonical(StaticEnv::DNE, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(ret == path{});
+ }
+ ec.clear();
+ {
+ const path ret = canonical(StaticEnv::DNE, StaticEnv::Root, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(ret == path{});
+ }
+ {
+ TEST_CHECK_THROW(filesystem_error, canonical(StaticEnv::DNE));
+ TEST_CHECK_THROW(filesystem_error, canonical(StaticEnv::DNE, StaticEnv::Root));
+ }
+}
+
+TEST_CASE(test_exception_contains_paths)
+{
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ const path p = "blabla/dne";
+ const path base = StaticEnv::Root;
+ try {
+ canonical(p, base);
+ TEST_REQUIRE(false);
+ } catch (filesystem_error const& err) {
+ TEST_CHECK(err.path1() == p);
+ TEST_CHECK(err.path2() == base);
+ }
+ try {
+ canonical(p);
+ TEST_REQUIRE(false);
+ } catch (filesystem_error const& err) {
+ TEST_CHECK(err.path1() == p);
+ TEST_CHECK(err.path2() == current_path());
+ }
+#endif
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp
new file mode 100644
index 00000000000..8e55aec3489
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp
@@ -0,0 +1,251 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// void copy(const path& from, const path& to);
+// void copy(const path& from, const path& to, error_code& ec) noexcept;
+// void copy(const path& from, const path& to, copy_options options);
+// void copy(const path& from, const path& to, copy_options options,
+// error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+using CO = fs::copy_options;
+
+TEST_SUITE(filesystem_copy_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ const copy_options opts{}; ((void)opts);
+ ASSERT_NOT_NOEXCEPT(fs::copy(p, p));
+ ASSERT_NOEXCEPT(fs::copy(p, p, ec));
+ ASSERT_NOT_NOEXCEPT(copy(p, p, opts));
+ ASSERT_NOEXCEPT(copy(p, p, opts, ec));
+}
+
+// There are 4 cases is the proposal for absolute path.
+// Each scope tests one of the cases.
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::copy(f, t);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == t
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path dir = env.create_dir("dir");
+ const path fifo = env.create_fifo("fifo");
+ TEST_REQUIRE(is_other(fifo));
+
+ // !exists(f)
+ {
+ std::error_code ec;
+ const path f = StaticEnv::DNE;
+ const path t = env.test_root;
+ fs::copy(f, t, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(f, t, ec));
+ }
+ { // equivalent(f, t) == true
+ std::error_code ec;
+ fs::copy(file, file, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(file, file, ec));
+ }
+ { // is_directory(from) && is_file(to)
+ std::error_code ec;
+ fs::copy(dir, file, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(dir, file, ec));
+ }
+ { // is_other(from)
+ std::error_code ec;
+ fs::copy(fifo, dir, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(fifo, dir, ec));
+ }
+ { // is_other(to)
+ std::error_code ec;
+ fs::copy(file, fifo, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(file, fifo, ec));
+ }
+}
+
+TEST_CASE(from_is_symlink)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path symlink = env.create_symlink(file, "sym");
+ const path dne = env.make_env_path("dne");
+
+ { // skip symlinks
+ std::error_code ec;
+ fs::copy(symlink, dne, copy_options::skip_symlinks, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(dne));
+ }
+ {
+ const path dest = env.make_env_path("dest");
+ std::error_code ec;
+ fs::copy(symlink, dest, copy_options::copy_symlinks, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(exists(dest));
+ TEST_CHECK(is_symlink(dest));
+ }
+ { // copy symlink but target exists
+ std::error_code ec;
+ fs::copy(symlink, file, copy_options::copy_symlinks, ec);
+ TEST_CHECK(ec);
+ }
+ { // create symlinks but target exists
+ std::error_code ec;
+ fs::copy(symlink, file, copy_options::create_symlinks, ec);
+ TEST_CHECK(ec);
+ }
+}
+
+TEST_CASE(from_is_regular_file)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path dir = env.create_dir("dir");
+ { // skip copy because of directory
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ fs::copy(file, dest, CO::directories_only, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(dest));
+ }
+ { // create symlink to file
+ const path dest = env.make_env_path("sym");
+ std::error_code ec;
+ fs::copy(file, dest, CO::create_symlinks, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_symlink(dest));
+ TEST_CHECK(equivalent(file, canonical(dest)));
+ }
+ { // create hard link to file
+ const path dest = env.make_env_path("hardlink");
+ TEST_CHECK(hard_link_count(file) == 1);
+ std::error_code ec;
+ fs::copy(file, dest, CO::create_hard_links, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(exists(dest));
+ TEST_CHECK(hard_link_count(file) == 2);
+ }
+ { // is_directory(t)
+ const path dest_dir = env.create_dir("dest_dir");
+ const path expect_dest = dest_dir / file.filename();
+ std::error_code ec;
+ fs::copy(file, dest_dir, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_regular_file(expect_dest));
+ }
+ { // otherwise copy_file(from, to, ...)
+ const path dest = env.make_env_path("file_copy");
+ std::error_code ec;
+ fs::copy(file, dest, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_regular_file(dest));
+ }
+}
+
+TEST_CASE(from_is_directory)
+{
+ struct FileInfo {
+ path filename;
+ int size;
+ };
+ const FileInfo files[] = {
+ {"file1", 0},
+ {"file2", 42},
+ {"file3", 300}
+ };
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path nested_dir_name = "dir2";
+ const path nested_dir = env.create_dir("dir/dir2");
+
+ for (auto& FI : files) {
+ env.create_file(dir / FI.filename, FI.size);
+ env.create_file(nested_dir / FI.filename, FI.size);
+ }
+ { // test for non-existant directory
+ const path dest = env.make_env_path("dest_dir1");
+ std::error_code ec;
+ fs::copy(dir, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_directory(dest));
+ for (auto& FI : files) {
+ path created = dest / FI.filename;
+ TEST_CHECK(is_regular_file(created));
+ TEST_CHECK(file_size(created) == FI.size);
+ }
+ TEST_CHECK(!is_directory(dest / nested_dir_name));
+ }
+ { // test for existing directory
+ const path dest = env.create_dir("dest_dir2");
+ std::error_code ec;
+ fs::copy(dir, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_directory(dest));
+ for (auto& FI : files) {
+ path created = dest / FI.filename;
+ TEST_CHECK(is_regular_file(created));
+ TEST_CHECK(file_size(created) == FI.size);
+ }
+ TEST_CHECK(!is_directory(dest / nested_dir_name));
+ }
+ { // test recursive copy
+ const path dest = env.make_env_path("dest_dir3");
+ std::error_code ec;
+ fs::copy(dir, dest, CO::recursive, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_directory(dest));
+ const path nested_dest = dest / nested_dir_name;
+ TEST_REQUIRE(is_directory(nested_dest));
+ for (auto& FI : files) {
+ path created = dest / FI.filename;
+ path nested_created = nested_dest / FI.filename;
+ TEST_CHECK(is_regular_file(created));
+ TEST_CHECK(file_size(created) == FI.size);
+ TEST_CHECK(is_regular_file(nested_created));
+ TEST_CHECK(file_size(nested_created) == FI.size);
+ }
+ }
+
+}
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
new file mode 100644
index 00000000000..0f43901f851
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
@@ -0,0 +1,165 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool copy_file(const path& from, const path& to);
+// bool copy_file(const path& from, const path& to, error_code& ec) noexcept;
+// bool copy_file(const path& from, const path& to, copy_options options);
+// bool copy_file(const path& from, const path& to, copy_options options,
+// error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+using CO = fs::copy_options;
+
+TEST_SUITE(filesystem_copy_file_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ const copy_options opts{}; ((void)opts);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, ec)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts, ec)), bool);
+ ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p));
+ ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts));
+ ASSERT_NOEXCEPT(fs::copy_file(p, p, ec));
+ ASSERT_NOEXCEPT(fs::copy_file(p, p, opts, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::copy_file(f, t);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == t
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path file2 = env.create_file("file2", 55);
+ const path dne = env.make_env_path("dne");
+ { // exists(to) && equivalent(to, from)
+ std::error_code ec;
+ TEST_CHECK(fs::copy_file(file, file, ec) == false);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(file, file, ec));
+ }
+ { // exists(to) && !(skip_existing | overwrite_existing | update_existing)
+ std::error_code ec;
+ TEST_CHECK(fs::copy_file(file, file2, ec) == false);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(file, file2, ec));
+ }
+}
+
+TEST_CASE(copy_file)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+
+ { // !exists(to)
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ TEST_REQUIRE(fs::copy_file(file, dest, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(dest) == 42);
+ }
+ { // exists(to) && overwrite_existing
+ const path dest = env.create_file("dest2", 55);
+ std::error_code ec;
+ TEST_REQUIRE(fs::copy_file(file, dest,
+ copy_options::overwrite_existing, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(dest) == 42);
+ }
+ { // exists(to) && update_existing
+ using Sec = std::chrono::seconds;
+ const path older = env.create_file("older_file", 1);
+
+ std::this_thread::sleep_for(Sec(2));
+ const path from = env.create_file("update_from", 55);
+
+ std::this_thread::sleep_for(Sec(2));
+ const path newer = env.create_file("newer_file", 2);
+
+ std::error_code ec;
+ TEST_REQUIRE(fs::copy_file(from, older, copy_options::update_existing, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(older) == 55);
+
+ TEST_REQUIRE(fs::copy_file(from, newer, copy_options::update_existing, ec) == false);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(newer) == 2);
+ }
+ { // skip_existing
+ const path file2 = env.create_file("file2", 55);
+ std::error_code ec;
+ TEST_REQUIRE(fs::copy_file(file, file2, copy_options::skip_existing, ec) == false);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(file2) == 55);
+ }
+}
+
+TEST_CASE(test_attributes_get_copied)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path dest = env.make_env_path("file2");
+ auto st = status(file);
+ perms default_perms = st.permissions();
+ perms new_perms = perms::owner_read;
+ permissions(file, new_perms);
+ std::error_code ec;
+ TEST_REQUIRE(fs::copy_file(file, dest, ec) == true);
+ TEST_CHECK(!ec);
+ auto new_st = status(dest);
+ TEST_CHECK(new_st.permissions() == new_perms);
+}
+
+TEST_CASE(copy_dir_test)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path dest = env.create_dir("dir1");
+ std::error_code ec;
+ TEST_CHECK(fs::copy_file(file, dest, ec) == false);
+ TEST_CHECK(ec);
+ ec.clear();
+ TEST_CHECK(fs::copy_file(dest, file, ec) == false);
+ TEST_CHECK(ec);
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp
new file mode 100644
index 00000000000..a95f6e334d8
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp
@@ -0,0 +1,110 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// void copy_symlink(const path& existing_symlink, const path& new_symlink);
+// void copy_symlink(const path& existing_symlink, const path& new_symlink,
+// error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_copy_symlink_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(fs::copy_symlink(p, p));
+ ASSERT_NOEXCEPT(fs::copy_symlink(p, p, ec));
+}
+
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::copy_symlink(f, t);
+ return true;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path file2 = env.create_file("file2", 55);
+ const path sym = env.create_symlink(file, "sym");
+ const path dir = env.create_dir("dir");
+ const path dne = env.make_env_path("dne");
+ { // from is a file, not a symlink
+ std::error_code ec;
+ fs::copy_symlink(file, dne, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(file, dne, ec));
+ }
+ { // from is a file, not a symlink
+ std::error_code ec;
+ fs::copy_symlink(dir, dne, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(dir, dne, ec));
+ }
+ { // destination exists
+ std::error_code ec;
+ fs::copy_symlink(sym, file2, ec);
+ TEST_REQUIRE(ec);
+ }
+}
+
+TEST_CASE(copy_symlink_basic)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dir_sym = env.create_symlink(dir, "dir_sym");
+ const path file = env.create_file("file", 42);
+ const path file_sym = env.create_symlink(file, "file_sym");
+ { // test for directory symlinks
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ fs::copy_symlink(dir_sym, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_symlink(dest));
+ TEST_CHECK(equivalent(dest, dir));
+ }
+ { // test for file symlinks
+ const path dest = env.make_env_path("dest2");
+ std::error_code ec;
+ fs::copy_symlink(file_sym, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_symlink(dest));
+ TEST_CHECK(equivalent(dest, file));
+ }
+}
+
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp
new file mode 100644
index 00000000000..7507042aec6
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool create_directories(const path& p);
+// bool create_directories(const path& p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_create_directories_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::create_directories(p)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::create_directories(p, ec)), bool);
+ ASSERT_NOT_NOEXCEPT(fs::create_directories(p));
+ ASSERT_NOEXCEPT(fs::create_directories(p, ec));
+}
+
+TEST_CASE(create_existing_directory)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir1");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directories(dir, ec) == false);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(dir));
+}
+
+TEST_CASE(create_directory_one_level)
+{
+ scoped_test_env env;
+ const path dir = env.make_env_path("dir1");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directories(dir, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(dir));
+}
+
+TEST_CASE(create_directories_multi_level)
+{
+ scoped_test_env env;
+ const path dir = env.make_env_path("dir1/dir2/dir3");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directories(dir, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(dir));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp
new file mode 100644
index 00000000000..6a7b8453801
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory.pass.cpp
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool create_directory(const path& p);
+// bool create_directory(const path& p, error_code& ec) noexcept;
+// bool create_directory(const path& p, const path& attr);
+// bool create_directory(const path& p, const path& attr, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_create_directory_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::create_directory(p)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::create_directory(p, ec)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p, ec)), bool);
+ ASSERT_NOT_NOEXCEPT(fs::create_directory(p));
+ ASSERT_NOEXCEPT(fs::create_directory(p, ec));
+ ASSERT_NOT_NOEXCEPT(fs::create_directory(p, p));
+ ASSERT_NOEXCEPT(fs::create_directory(p, p, ec));
+}
+
+
+TEST_CASE(create_existing_directory)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir1");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(dir, ec) == false);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(dir));
+ // Test throwing version
+ TEST_CHECK(fs::create_directory(dir) == false);
+}
+
+TEST_CASE(create_directory_one_level)
+{
+ scoped_test_env env;
+ const path dir = env.make_env_path("dir1");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(dir, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(dir));
+
+ auto st = status(dir);
+ perms owner_perms = perms::owner_all;
+ perms gperms = perms::group_all;
+ perms other_perms = perms::others_read | perms::others_exec;
+#if defined(__APPLE__) || defined(__FreeBSD__)
+ gperms = perms::group_read | perms::group_exec;
+#endif
+ TEST_CHECK((st.permissions() & perms::owner_all) == owner_perms);
+ TEST_CHECK((st.permissions() & perms::group_all) == gperms);
+ TEST_CHECK((st.permissions() & perms::others_all) == other_perms);
+}
+
+TEST_CASE(create_directory_multi_level)
+{
+ scoped_test_env env;
+ const path dir = env.make_env_path("dir1/dir2");
+ const path dir1 = env.make_env_path("dir1");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(dir, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(!is_directory(dir));
+ TEST_CHECK(!is_directory(dir1));
+}
+
+TEST_CASE(dest_is_file)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(file, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(is_regular_file(file));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp
new file mode 100644
index 00000000000..638fca23636
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory/create_directory_with_attributes.pass.cpp
@@ -0,0 +1,103 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool create_directory(const path& p, const path& attr);
+// bool create_directory(const path& p, const path& attr, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_create_directory_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::create_directory(p, p, ec)), bool);
+ ASSERT_NOT_NOEXCEPT(fs::create_directory(p, p));
+ ASSERT_NOEXCEPT(fs::create_directory(p, p, ec));
+}
+
+TEST_CASE(create_existing_directory)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir1");
+ const path dir2 = env.create_dir("dir2");
+
+ const perms orig_p = status(dir).permissions();
+ permissions(dir2, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(dir, dir2, ec) == false);
+ TEST_CHECK(!ec);
+
+ // Check that the permissions were unchanged
+ TEST_CHECK(orig_p == status(dir).permissions());
+
+ // Test throwing version
+ TEST_CHECK(fs::create_directory(dir, dir2) == false);
+}
+
+TEST_CASE(create_directory_one_level)
+{
+ scoped_test_env env;
+ const path dir = env.make_env_path("dir1");
+ const path attr_dir = env.create_dir("dir2");
+ permissions(attr_dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(dir, attr_dir, ec) == true);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_directory(dir));
+
+ // Check that the new directory has the same permissions as attr_dir
+ auto st = status(dir);
+ TEST_CHECK(st.permissions() == perms::none);
+}
+
+TEST_CASE(create_directory_multi_level)
+{
+ scoped_test_env env;
+ const path dir = env.make_env_path("dir1/dir2");
+ const path dir1 = env.make_env_path("dir1");
+ const path attr_dir = env.create_dir("attr_dir");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(dir, attr_dir, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(!is_directory(dir));
+ TEST_CHECK(!is_directory(dir1));
+}
+
+TEST_CASE(dest_is_file)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path attr_dir = env.create_dir("attr_dir");
+ std::error_code ec;
+ TEST_CHECK(fs::create_directory(file, attr_dir, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK(is_regular_file(file));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp
new file mode 100644
index 00000000000..e0473754cc8
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directory_symlink/create_directory_symlink.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// void create_directory_symlink(const path& existing_symlink, const path& new_symlink);
+// void create_directory_symlink(const path& existing_symlink, const path& new_symlink,
+// error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_create_directory_symlink_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(fs::create_directory_symlink(p, p));
+ ASSERT_NOEXCEPT(fs::create_directory_symlink(p, p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::create_directory_symlink(f, t);
+ return true;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path file2 = env.create_file("file2", 55);
+ const path sym = env.create_symlink(file, "sym");
+ { // destination exists
+ std::error_code ec;
+ fs::create_directory_symlink(sym, file2, ec);
+ TEST_REQUIRE(ec);
+ }
+}
+
+TEST_CASE(create_directory_symlink_basic)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dir_sym = env.create_symlink(dir, "dir_sym");
+
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ fs::create_directory_symlink(dir_sym, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_symlink(dest));
+ TEST_CHECK(equivalent(dest, dir));
+}
+
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp
new file mode 100644
index 00000000000..4a865fdee7e
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_hard_link/create_hard_link.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// void create_hard_link(const path& existing_symlink, const path& new_symlink);
+// void create_hard_link(const path& existing_symlink, const path& new_symlink,
+// error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_create_hard_link_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(fs::create_hard_link(p, p));
+ ASSERT_NOEXCEPT(fs::create_hard_link(p, p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::create_hard_link(f, t);
+ return true;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path file2 = env.create_file("file2", 55);
+ const path sym = env.create_symlink(file, "sym");
+ { // destination exists
+ std::error_code ec;
+ fs::create_hard_link(sym, file2, ec);
+ TEST_REQUIRE(ec);
+ }
+}
+
+TEST_CASE(create_file_hard_link)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file");
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ TEST_CHECK(hard_link_count(file) == 1);
+ fs::create_hard_link(file, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(exists(dest));
+ TEST_CHECK(equivalent(dest, file));
+ TEST_CHECK(hard_link_count(file) == 2);
+}
+
+TEST_CASE(create_directory_hard_link_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dest = env.make_env_path("dest2");
+ std::error_code ec;
+
+ fs::create_hard_link(dir, dest, ec);
+ TEST_REQUIRE(ec);
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp
new file mode 100644
index 00000000000..35ba57f3ab4
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// void create_symlink(const path& existing_symlink, const path& new_symlink);
+// void create_symlink(const path& existing_symlink, const path& new_symlink,
+// error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_create_symlink_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(fs::create_symlink(p, p));
+ ASSERT_NOEXCEPT(fs::create_symlink(p, p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::create_symlink(f, t);
+ return true;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path file2 = env.create_file("file2", 55);
+ const path sym = env.create_symlink(file, "sym");
+ { // destination exists
+ std::error_code ec;
+ fs::create_symlink(sym, file2, ec);
+ TEST_REQUIRE(ec);
+ }
+}
+
+TEST_CASE(create_symlink_basic)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path file_sym = env.create_symlink(file, "file_sym");
+ const path dir = env.create_dir("dir");
+ const path dir_sym = env.create_symlink(dir, "dir_sym");
+ {
+ const path dest = env.make_env_path("dest1");
+ std::error_code ec;
+ fs::create_symlink(file_sym, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_symlink(dest));
+ TEST_CHECK(equivalent(dest, file));
+ }
+ {
+ const path dest = env.make_env_path("dest2");
+ std::error_code ec;
+ fs::create_symlink(dir_sym, dest, ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(is_symlink(dest));
+ TEST_CHECK(equivalent(dest, dir));
+ }
+}
+
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp
new file mode 100644
index 00000000000..9d004ab854c
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.current_path/current_path.pass.cpp
@@ -0,0 +1,93 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// path current_path();
+// path current_path(error_code& ec);
+// void current_path(path const&);
+// void current_path(path const&, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(filesystem_current_path_path_test_suite)
+
+TEST_CASE(current_path_signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(current_path());
+ ASSERT_NOT_NOEXCEPT(current_path(ec));
+ ASSERT_NOT_NOEXCEPT(current_path(p));
+ ASSERT_NOEXCEPT(current_path(p, ec));
+}
+
+TEST_CASE(current_path_test)
+{
+ std::error_code ec;
+ const path p = current_path(ec);
+ TEST_REQUIRE(!ec);
+ TEST_CHECK(p.is_absolute());
+ TEST_CHECK(is_directory(p));
+
+ const path p2 = current_path();
+ TEST_CHECK(p2 == p);
+}
+
+TEST_CASE(current_path_after_change_test)
+{
+ const path new_path = StaticEnv::Dir;
+ current_path(new_path);
+ TEST_CHECK(current_path() == new_path);
+}
+
+TEST_CASE(current_path_is_file_test)
+{
+ const path p = StaticEnv::File;
+ std::error_code ec;
+ const path old_p = current_path();
+ current_path(p, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(old_p == current_path());
+}
+
+TEST_CASE(set_to_non_absolute_path)
+{
+ const path base = StaticEnv::Dir;
+ current_path(base);
+ const path p = StaticEnv::Dir2.filename();
+ std::error_code ec;
+ current_path(p, ec);
+ TEST_CHECK(!ec);
+ const path new_cwd = current_path();
+ TEST_CHECK(new_cwd == StaticEnv::Dir2);
+ TEST_CHECK(new_cwd.is_absolute());
+}
+
+TEST_CASE(set_to_empty)
+{
+ const path p = "";
+ std::error_code ec;
+ const path old_p = current_path();
+ current_path(p, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(old_p == current_path());
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp
new file mode 100644
index 00000000000..621ff8305fc
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool equivalent(path const& lhs, path const& rhs);
+// bool equivalent(path const& lhs, path const& rhs, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(equivalent_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(equivalent(p, p, ec));
+ ASSERT_NOT_NOEXCEPT(equivalent(p, p));
+}
+
+TEST_CASE(equivalent_test)
+{
+ struct TestCase {
+ path lhs;
+ path rhs;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {StaticEnv::Dir, StaticEnv::Dir, true},
+ {StaticEnv::File, StaticEnv::Dir, false},
+ {StaticEnv::Dir, StaticEnv::SymlinkToDir, true},
+ {StaticEnv::Dir, StaticEnv::SymlinkToFile, false},
+ {StaticEnv::File, StaticEnv::File, true},
+ {StaticEnv::File, StaticEnv::SymlinkToFile, true},
+ };
+ for (auto& TC : testCases) {
+ std::error_code ec;
+ TEST_CHECK(equivalent(TC.lhs, TC.rhs, ec) == TC.expect);
+ TEST_CHECK(!ec);
+ }
+}
+
+TEST_CASE(equivalent_reports_double_dne)
+{
+ const path E = StaticEnv::File;
+ const path DNE = StaticEnv::DNE;
+ { // Test that no exception is thrown if one of the paths exists
+ TEST_CHECK(equivalent(E, DNE) == false);
+ TEST_CHECK(equivalent(DNE, E) == false);
+ }
+ { // Test that an exception is thrown if both paths do not exist.
+ TEST_CHECK_THROW(filesystem_error, equivalent(DNE, DNE));
+ }
+ {
+ std::error_code ec;
+ TEST_CHECK(equivalent(DNE, DNE, ec) == false);
+ TEST_CHECK(ec);
+ }
+}
+
+TEST_CASE(equivalent_is_other_succeeds)
+{
+ scoped_test_env env;
+ path const file = env.create_file("file", 42);
+ const path hl1 = env.create_hardlink(file, "hl1");
+ const path hl2 = env.create_hardlink(file, "hl2");
+ TEST_CHECK(equivalent(file, hl1));
+ TEST_CHECK(equivalent(file, hl2));
+ TEST_CHECK(equivalent(hl1, hl2));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp
new file mode 100644
index 00000000000..460b8be6b12
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.exists/exists.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool exists(file_status s) noexcept
+// bool exists(path const& p);
+// bool exists(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(exists_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(exists(s));
+ ASSERT_NOEXCEPT(exists(p, ec));
+ ASSERT_NOT_NOEXCEPT(exists(p));
+}
+
+TEST_CASE(exists_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, true},
+ {file_type::directory, true},
+ {file_type::symlink, true},
+ {file_type::block, true},
+ {file_type::character, true},
+ {file_type::fifo, true},
+ {file_type::socket, true},
+ {file_type::unknown, true}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(exists(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(exists(p) == false);
+}
+
+TEST_CASE(test_exists_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(exists(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, exists(file));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp
new file mode 100644
index 00000000000..460e42dd1c3
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.file_size/file_size.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// uintmax_t file_size(const path& p);
+// uintmax_t file_size(const path& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(file_size_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(file_size(p)), uintmax_t);
+ ASSERT_SAME_TYPE(decltype(file_size(p, ec)), uintmax_t);
+ ASSERT_NOT_NOEXCEPT(file_size(p));
+ ASSERT_NOEXCEPT(file_size(p, ec));
+}
+
+TEST_CASE(file_size_empty_test)
+{
+ const path p = StaticEnv::EmptyFile;
+ TEST_CHECK(file_size(p) == 0);
+ std::error_code ec;
+ TEST_CHECK(file_size(p, ec) == 0);
+}
+
+TEST_CASE(file_size_non_empty)
+{
+ scoped_test_env env;
+ const path p = env.create_file("file", 42);
+ TEST_CHECK(file_size(p) == 42);
+ std::error_code ec;
+ TEST_CHECK(file_size(p, ec) == 42);
+}
+
+TEST_CASE(symlink_test_case)
+{
+ const path p = StaticEnv::File;
+ const path p2 = StaticEnv::SymlinkToFile;
+ TEST_CHECK(file_size(p) == file_size(p2));
+}
+
+TEST_CASE(file_size_error_cases)
+{
+ const path testCases[] = {
+ StaticEnv::Dir,
+ StaticEnv::SymlinkToDir,
+ StaticEnv::BadSymlink,
+ StaticEnv::DNE
+ };
+ const uintmax_t expect = static_cast<uintmax_t>(-1);
+ for (auto& TC : testCases) {
+ std::error_code ec;
+ TEST_CHECK(file_size(TC, ec) == expect);
+ TEST_CHECK(ec);
+ }
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp
new file mode 100644
index 00000000000..abc50e9c6a4
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.hard_lk_ct/hard_link_count.pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// uintmax_t hard_link_count(const path& p);
+// uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(hard_link_count_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(hard_link_count(p)), uintmax_t);
+ ASSERT_SAME_TYPE(decltype(hard_link_count(p, ec)), uintmax_t);
+ ASSERT_NOT_NOEXCEPT(hard_link_count(p));
+ ASSERT_NOEXCEPT(hard_link_count(p, ec));
+}
+
+TEST_CASE(hard_link_count_for_file)
+{
+ TEST_CHECK(hard_link_count(StaticEnv::File) == 1);
+ std::error_code ec;
+ TEST_CHECK(hard_link_count(StaticEnv::File, ec) == 1);
+}
+
+TEST_CASE(hard_link_count_for_directory)
+{
+ uintmax_t DirExpect = 3;
+ uintmax_t Dir3Expect = 2;
+#if defined(__APPLE__)
+ DirExpect += 2;
+ Dir3Expect += 1;
+#endif
+ TEST_CHECK(hard_link_count(StaticEnv::Dir) == DirExpect);
+ TEST_CHECK(hard_link_count(StaticEnv::Dir3) == Dir3Expect);
+
+ std::error_code ec;
+ TEST_CHECK(hard_link_count(StaticEnv::Dir, ec) == DirExpect);
+ TEST_CHECK(hard_link_count(StaticEnv::Dir3, ec) == Dir3Expect);
+}
+TEST_CASE(hard_link_count_increments_test)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ TEST_CHECK(hard_link_count(file) == 1);
+
+ env.create_hardlink(file, "file_hl");
+ TEST_CHECK(hard_link_count(file) == 2);
+}
+
+
+TEST_CASE(hard_link_count_error_cases)
+{
+ const path testCases[] = {
+ StaticEnv::BadSymlink,
+ StaticEnv::DNE
+ };
+ const uintmax_t expect = static_cast<uintmax_t>(-1);
+ for (auto& TC : testCases) {
+ std::error_code ec;
+ TEST_CHECK(hard_link_count(TC, ec) == expect);
+ TEST_CHECK(ec);
+ }
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp
new file mode 100644
index 00000000000..dee28aa5be6
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool is_block_file(file_status s) noexcept
+// bool is_block_file(path const& p);
+// bool is_block_file(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_block_file_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_block_file(s));
+ ASSERT_NOEXCEPT(is_block_file(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_block_file(p));
+}
+
+TEST_CASE(is_block_file_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, false},
+ {file_type::symlink, false},
+ {file_type::block, true},
+ {file_type::character, false},
+ {file_type::fifo, false},
+ {file_type::socket, false},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_block_file(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_block_file(p) == false);
+}
+
+TEST_CASE(test_is_block_file_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_block_file(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_block_file(file));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp
new file mode 100644
index 00000000000..2de42bf2097
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool is_character_file(file_status s) noexcept
+// bool is_character_file(path const& p);
+// bool is_character_file(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_character_file_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_character_file(s));
+ ASSERT_NOEXCEPT(is_character_file(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_character_file(p));
+}
+
+TEST_CASE(is_character_file_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, false},
+ {file_type::symlink, false},
+ {file_type::block, false},
+ {file_type::character, true},
+ {file_type::fifo, false},
+ {file_type::socket, false},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_character_file(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_character_file(p) == false);
+}
+
+TEST_CASE(test_is_character_file_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_character_file(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_character_file(file));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp
new file mode 100644
index 00000000000..d6ecb1a1e68
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool is_directory(file_status s) noexcept
+// bool is_directory(path const& p);
+// bool is_directory(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_directory_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_directory(s));
+ ASSERT_NOEXCEPT(is_directory(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_directory(p));
+}
+
+TEST_CASE(is_directory_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, true},
+ {file_type::symlink, false},
+ {file_type::block, false},
+ {file_type::character, false},
+ {file_type::fifo, false},
+ {file_type::socket, false},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_directory(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_directory(p) == false);
+}
+
+TEST_CASE(static_env_test)
+{
+ TEST_CHECK(is_directory(StaticEnv::Dir));
+ TEST_CHECK(is_directory(StaticEnv::SymlinkToDir));
+ TEST_CHECK(!is_directory(StaticEnv::File));
+}
+
+TEST_CASE(test_is_directory_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dir2 = env.create_dir("dir/dir2");
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_directory(dir2, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_directory(dir2));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp
new file mode 100644
index 00000000000..ba07d09d10d
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool is_empty(path const& p);
+// bool is_empty(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_empty_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_empty(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_empty(p));
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ std::error_code ec;
+ TEST_CHECK(is_empty(p, ec) == false);
+ TEST_CHECK(ec);
+ TEST_CHECK_THROW(filesystem_error, is_empty(p));
+}
+
+TEST_CASE(test_is_empty_directory)
+{
+ TEST_CHECK(!is_empty(StaticEnv::Dir));
+ TEST_CHECK(!is_empty(StaticEnv::SymlinkToDir));
+}
+
+TEST_CASE(test_is_empty_directory_dynamic)
+{
+ scoped_test_env env;
+ TEST_CHECK(is_empty(env.test_root));
+ env.create_file("foo", 42);
+ TEST_CHECK(!is_empty(env.test_root));
+}
+
+TEST_CASE(test_is_empty_file)
+{
+ TEST_CHECK(is_empty(StaticEnv::EmptyFile));
+ TEST_CHECK(!is_empty(StaticEnv::NonEmptyFile));
+}
+
+TEST_CASE(test_is_empty_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dir2 = env.create_dir("dir/dir2");
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_empty(dir2, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_empty(dir2));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp
new file mode 100644
index 00000000000..44892f65d86
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool is_fifo(file_status s) noexcept
+// bool is_fifo(path const& p);
+// bool is_fifo(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_fifo_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_fifo(s));
+ ASSERT_NOEXCEPT(is_fifo(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_fifo(p));
+}
+
+TEST_CASE(is_fifo_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, false},
+ {file_type::symlink, false},
+ {file_type::block, false},
+ {file_type::character, false},
+ {file_type::fifo, true},
+ {file_type::socket, false},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_fifo(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_fifo(p) == false);
+}
+
+TEST_CASE(test_is_fifo_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_fifo(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_fifo(file));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp
new file mode 100644
index 00000000000..e86b66b4ea6
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_other/is_other.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool is_other(file_status s) noexcept
+// bool is_other(path const& p);
+// bool is_other(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_other_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_other(s));
+ ASSERT_NOEXCEPT(is_other(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_other(p));
+}
+
+TEST_CASE(is_other_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, false},
+ {file_type::symlink, false},
+ {file_type::block, true},
+ {file_type::character, true},
+ {file_type::fifo, true},
+ {file_type::socket, true},
+ {file_type::unknown, true}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_other(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_other(p) == false);
+}
+
+TEST_CASE(test_is_other_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_other(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_other(file));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp
new file mode 100644
index 00000000000..be68dcfc35d
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool is_regular_file(file_status s) noexcept
+// bool is_regular_file(path const& p);
+// bool is_regular_file(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_regular_file_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_regular_file(s));
+ ASSERT_NOEXCEPT(is_regular_file(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_regular_file(p));
+}
+
+TEST_CASE(is_regular_file_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, true},
+ {file_type::directory, false},
+ {file_type::symlink, false},
+ {file_type::block, false},
+ {file_type::character, false},
+ {file_type::fifo, false},
+ {file_type::socket, false},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_regular_file(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_regular_file(p) == false);
+ std::error_code ec;
+ TEST_CHECK(is_regular_file(p, ec) == false);
+ TEST_CHECK(ec);
+}
+
+TEST_CASE(test_is_regular_file_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_regular_file(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_regular_file(file));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp
new file mode 100644
index 00000000000..49fd402eb54
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool is_socket(file_status s) noexcept
+// bool is_socket(path const& p);
+// bool is_socket(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_socket_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_socket(s));
+ ASSERT_NOEXCEPT(is_socket(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_socket(p));
+}
+
+TEST_CASE(is_socket_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, false},
+ {file_type::symlink, false},
+ {file_type::block, false},
+ {file_type::character, false},
+ {file_type::fifo, false},
+ {file_type::socket, true},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_socket(s) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_socket(p) == false);
+}
+
+TEST_CASE(test_is_socket_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_socket(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_socket(file));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp
new file mode 100644
index 00000000000..3de00297868
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp
@@ -0,0 +1,105 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool is_symlink(file_status s) noexcept
+// bool is_symlink(path const& p);
+// bool is_symlink(path const& p, std::error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(is_symlink_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOEXCEPT(is_symlink(s));
+ ASSERT_NOEXCEPT(is_symlink(p, ec));
+ ASSERT_NOT_NOEXCEPT(is_symlink(p));
+}
+
+TEST_CASE(is_symlink_status_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, false},
+ {file_type::regular, false},
+ {file_type::directory, false},
+ {file_type::symlink, true},
+ {file_type::block, false},
+ {file_type::character, false},
+ {file_type::fifo, false},
+ {file_type::socket, false},
+ {file_type::unknown, false}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(is_symlink(s) == TC.expect);
+ }
+}
+
+TEST_CASE(static_env_test)
+{
+ struct TestCase {
+ path p;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {StaticEnv::File, false},
+ {StaticEnv::Dir, false},
+ {StaticEnv::SymlinkToFile, true},
+ {StaticEnv::SymlinkToDir, true},
+ {StaticEnv::BadSymlink, true}
+ };
+ for (auto& TC : testCases) {
+ TEST_CHECK(is_symlink(TC.p) == TC.expect);
+ }
+}
+
+TEST_CASE(test_exist_not_found)
+{
+ const path p = StaticEnv::DNE;
+ TEST_CHECK(is_symlink(p) == false);
+ std::error_code ec;
+ TEST_CHECK(is_symlink(p, ec) == false);
+ TEST_CHECK(ec);
+}
+
+TEST_CASE(test_is_symlink_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec;
+ TEST_CHECK(is_symlink(file, ec) == false);
+ TEST_CHECK(ec);
+
+ TEST_CHECK_THROW(filesystem_error, is_symlink(file));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
new file mode 100644
index 00000000000..bcba502f417
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
@@ -0,0 +1,297 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// file_time_type last_write_time(const path& p);
+// file_time_type last_write_time(const path& p, std::error_code& ec) noexcept;
+// void last_write_time(const path& p, file_time_type new_time);
+// void last_write_time(const path& p, file_time_type new_type,
+// std::error_code& ec) noexcept;
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <fstream>
+#include <iostream>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+#include <sys/stat.h>
+
+using namespace std::experimental::filesystem;
+
+
+std::pair<std::time_t, std::time_t> GetTimes(path const& p) {
+ using Clock = file_time_type::clock;
+ struct ::stat st;
+ if (::stat(p.c_str(), &st) == -1) {
+ std::error_code ec(errno, std::generic_category());
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ throw ec;
+#else
+ std::cerr << ec.message() << std::endl;
+ std::exit(EXIT_FAILURE);
+#endif
+ }
+ return {st.st_atime, st.st_mtime};
+}
+
+std::time_t LastAccessTime(path const& p) {
+ return GetTimes(p).first;
+}
+
+std::time_t LastWriteTime(path const& p) {
+ return GetTimes(p).second;
+}
+
+std::pair<std::time_t, std::time_t> GetSymlinkTimes(path const& p) {
+ using Clock = file_time_type::clock;
+ struct ::stat st;
+ if (::lstat(p.c_str(), &st) == -1) {
+ std::error_code ec(errno, std::generic_category());
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ throw ec;
+#else
+ std::cerr << ec.message() << std::endl;
+ std::exit(EXIT_FAILURE);
+#endif
+ }
+ return {st.st_atime, st.st_mtime};
+}
+
+
+TEST_SUITE(exists_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const file_time_type t;
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(last_write_time(p)), file_time_type);
+ ASSERT_SAME_TYPE(decltype(last_write_time(p, ec)), file_time_type);
+ ASSERT_SAME_TYPE(decltype(last_write_time(p, t)), void);
+ ASSERT_SAME_TYPE(decltype(last_write_time(p, t, ec)), void);
+ ASSERT_NOT_NOEXCEPT(last_write_time(p));
+ ASSERT_NOT_NOEXCEPT(last_write_time(p, t));
+ ASSERT_NOEXCEPT(last_write_time(p, ec));
+ ASSERT_NOEXCEPT(last_write_time(p, t, ec));
+}
+
+TEST_CASE(read_last_write_time_static_env_test)
+{
+ using C = file_time_type::clock;
+ file_time_type min = file_time_type::min();
+ {
+ file_time_type ret = last_write_time(StaticEnv::File);
+ TEST_CHECK(ret != min);
+ TEST_CHECK(ret < C::now());
+ TEST_CHECK(C::to_time_t(ret) == LastWriteTime(StaticEnv::File));
+
+ file_time_type ret2 = last_write_time(StaticEnv::SymlinkToFile);
+ TEST_CHECK(ret == ret2);
+ TEST_CHECK(C::to_time_t(ret2) == LastWriteTime(StaticEnv::SymlinkToFile));
+ }
+ {
+ file_time_type ret = last_write_time(StaticEnv::Dir);
+ TEST_CHECK(ret != min);
+ TEST_CHECK(ret < C::now());
+ TEST_CHECK(C::to_time_t(ret) == LastWriteTime(StaticEnv::Dir));
+
+ file_time_type ret2 = last_write_time(StaticEnv::SymlinkToDir);
+ TEST_CHECK(ret == ret2);
+ TEST_CHECK(C::to_time_t(ret2) == LastWriteTime(StaticEnv::SymlinkToDir));
+ }
+}
+
+TEST_CASE(get_last_write_time_dynamic_env_test)
+{
+ using Clock = file_time_type::clock;
+ using Sec = std::chrono::seconds;
+ scoped_test_env env;
+
+ const path file = env.create_file("file", 42);
+ const path dir = env.create_dir("dir");
+
+ const auto file_times = GetTimes(file);
+ const std::time_t file_access_time = file_times.first;
+ const std::time_t file_write_time = file_times.second;
+ const auto dir_times = GetTimes(dir);
+ const std::time_t dir_access_time = dir_times.first;
+ const std::time_t dir_write_time = dir_times.second;
+
+ file_time_type ftime = last_write_time(file);
+ TEST_CHECK(Clock::to_time_t(ftime) == file_write_time);
+
+ file_time_type dtime = last_write_time(dir);
+ TEST_CHECK(Clock::to_time_t(dtime) == dir_write_time);
+
+ std::this_thread::sleep_for(Sec(2));
+
+ // update file and add a file to the directory. Make sure the times increase.
+ std::ofstream of(file, std::ofstream::app);
+ of << "hello";
+ of.close();
+ env.create_file("dir/file1", 1);
+
+ file_time_type ftime2 = last_write_time(file);
+ file_time_type dtime2 = last_write_time(dir);
+
+ TEST_CHECK(ftime2 > ftime);
+ TEST_CHECK(dtime2 > dtime);
+ TEST_CHECK(LastAccessTime(file) == file_access_time);
+ TEST_CHECK(LastAccessTime(dir) == dir_access_time);
+}
+
+
+TEST_CASE(set_last_write_time_dynamic_env_test)
+{
+ using Clock = file_time_type::clock;
+ using Sec = std::chrono::seconds;
+ using Hours = std::chrono::hours;
+ using Minutes = std::chrono::minutes;
+
+ scoped_test_env env;
+
+ const path file = env.create_file("file", 42);
+ const path dir = env.create_dir("dir");
+
+ const file_time_type future_time = Clock::now() + Hours(3);
+ const file_time_type past_time = Clock::now() - Minutes(3);
+
+ struct TestCase {
+ path p;
+ file_time_type new_time;
+ } cases[] = {
+ {file, future_time},
+ {dir, future_time},
+ {file, past_time},
+ {dir, past_time}
+ };
+ for (const auto& TC : cases) {
+ const auto old_times = GetTimes(TC.p);
+
+ std::error_code ec = GetTestEC();
+ last_write_time(TC.p, TC.new_time, ec);
+ TEST_CHECK(!ec);
+
+ const std::time_t new_time_t = Clock::to_time_t(TC.new_time);
+ file_time_type got_time = last_write_time(TC.p);
+ std::time_t got_time_t = Clock::to_time_t(got_time);
+
+ TEST_CHECK(got_time_t != old_times.second);
+ TEST_CHECK(got_time_t == new_time_t);
+ TEST_CHECK(LastAccessTime(TC.p) == old_times.first);
+ }
+}
+
+TEST_CASE(last_write_time_symlink_test)
+{
+ using Clock = file_time_type::clock;
+ using Sec = std::chrono::seconds;
+ using Hours = std::chrono::hours;
+ using Minutes = std::chrono::minutes;
+
+ scoped_test_env env;
+
+ const path file = env.create_file("file", 42);
+ const path sym = env.create_symlink("file", "sym");
+
+ const file_time_type new_time = Clock::now() + Hours(3);
+
+ const auto old_times = GetTimes(sym);
+ const auto old_sym_times = GetSymlinkTimes(sym);
+
+ std::error_code ec = GetTestEC();
+ last_write_time(sym, new_time, ec);
+ TEST_CHECK(!ec);
+
+ const std::time_t new_time_t = Clock::to_time_t(new_time);
+ file_time_type got_time = last_write_time(sym);
+ std::time_t got_time_t = Clock::to_time_t(got_time);
+
+ TEST_CHECK(got_time_t != old_times.second);
+ TEST_CHECK(got_time_t == new_time_t);
+ TEST_CHECK(LastWriteTime(file) == new_time_t);
+ TEST_CHECK(LastAccessTime(sym) == old_times.first);
+ TEST_CHECK(GetSymlinkTimes(sym) == old_sym_times);
+}
+
+TEST_CASE(test_write_min_max_time)
+{
+ using Clock = file_time_type::clock;
+ using Sec = std::chrono::seconds;
+ using Hours = std::chrono::hours;
+ scoped_test_env env;
+ const path p = env.create_file("file", 42);
+
+ file_time_type last_time = last_write_time(p);
+
+ file_time_type new_time = file_time_type::min();
+ std::error_code ec = GetTestEC();
+ last_write_time(p, new_time, ec);
+ file_time_type tt = last_write_time(p);
+ if (ec) {
+ TEST_CHECK(ec != GetTestEC());
+ TEST_CHECK(tt == last_time);
+ } else {
+ file_time_type max_allowed = new_time + Sec(1);
+ TEST_CHECK(tt >= new_time);
+ TEST_CHECK(tt < max_allowed);
+ }
+
+ last_time = tt;
+ new_time = file_time_type::max();
+ ec = GetTestEC();
+ last_write_time(p, new_time, ec);
+
+ tt = last_write_time(p);
+ if (ec) {
+ TEST_CHECK(ec != GetTestEC());
+ TEST_CHECK(tt == last_time);
+ } else {
+ file_time_type min_allowed = new_time - Sec(1);
+ TEST_CHECK(tt > min_allowed);
+ TEST_CHECK(tt <= new_time);
+ }
+}
+
+TEST_CASE(test_value_on_failure)
+{
+ const path p = StaticEnv::DNE;
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(last_write_time(p, ec) == file_time_type::min());
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+}
+
+TEST_CASE(test_exists_fails)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ permissions(dir, perms::none);
+
+ std::error_code ec = GetTestEC();
+ TEST_CHECK(last_write_time(file, ec) == file_time_type::min());
+ TEST_CHECK(ec);
+ TEST_CHECK(ec != GetTestEC());
+
+ TEST_CHECK_THROW(filesystem_error, last_write_time(file));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp
new file mode 100644
index 00000000000..74977c4eaca
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.permissions/permissions.pass.cpp
@@ -0,0 +1,154 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// void permissions(const path& p, perms prms);
+// void permissions(const path& p, perms prms, std::error_code& ec) noexcept;
+
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+using PR = fs::perms;
+
+TEST_SUITE(filesystem_permissions_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ const perms opts{}; ((void)opts);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(fs::permissions(p, opts));
+ // Not noexcept because of narrow contract
+ ASSERT_NOT_NOEXCEPT(fs::permissions(p, opts, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, fs::perms opts, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::permissions(f, opts);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == ""
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path dne_sym = env.create_symlink(dne, "dne_sym");
+ { // !exists
+ std::error_code ec;
+ fs::permissions(dne, fs::perms{}, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(dne, fs::perms{}, ec));
+ }
+ {
+ std::error_code ec;
+ fs::permissions(dne_sym, perms::resolve_symlinks, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(dne_sym, perms::resolve_symlinks, ec));
+ }
+}
+
+TEST_CASE(basic_permissions_test)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file1", 42);
+ const path dir = env.create_dir("dir1");
+ const path file_for_sym = env.create_file("file2", 42);
+ const path sym = env.create_symlink(file_for_sym, "sym");
+ const perms AP = perms::add_perms;
+ const perms RP = perms::remove_perms;
+ const perms RS = perms::resolve_symlinks;
+ struct TestCase {
+ path p;
+ perms set_perms;
+ perms expected;
+ } cases[] = {
+ // test file
+ {file, perms::owner_all, perms::owner_all},
+ {file, perms::group_all | AP, perms::owner_all | perms::group_all},
+ {file, perms::group_all | RP, perms::owner_all},
+ {file, perms::none, perms::none},
+ // test directory
+ {dir, perms::owner_all, perms::owner_all},
+ {dir, perms::group_all | AP, perms::owner_all | perms::group_all},
+ {dir, perms::group_all | RP, perms::owner_all},
+ {dir, perms::none, perms::none},
+ // test symlink with resolve symlinks on symlink
+ {sym, perms::owner_all | RS, perms::owner_all},
+ {sym, perms::group_all | AP | RS, perms::owner_all | perms::group_all},
+ {sym, perms::group_all | RP | RS, perms::owner_all},
+ {sym, perms::none | RS, perms::none}
+ };
+ for (auto const& TC : cases) {
+ TEST_CHECK(status(TC.p).permissions() != TC.expected);
+ // Set the error code to ensure it's cleared.
+ std::error_code ec = std::make_error_code(std::errc::bad_address);
+ permissions(TC.p, TC.set_perms, ec);
+ TEST_CHECK(!ec);
+ auto pp = status(TC.p).permissions();
+ TEST_CHECK(status(TC.p).permissions() == TC.expected);
+ }
+}
+
+TEST_CASE(test_no_resolve_symlink_on_symlink)
+{
+ scoped_test_env env;
+ const path file = env.create_file("file", 42);
+ const path sym = env.create_symlink(file, "sym");
+ const auto file_perms = status(file).permissions();
+
+ struct TestCase {
+ perms set_perms;
+ perms expected; // only expected on platform that support symlink perms.
+ } cases[] = {
+ {perms::owner_all, perms::owner_all},
+ {perms::group_all | perms::add_perms, perms::owner_all | perms::group_all},
+ {perms::owner_all | perms::remove_perms, perms::group_all},
+ };
+ for (auto const& TC : cases) {
+#if defined(__APPLE__) || defined(__FreeBSD__)
+ // On OS X symlink permissions are supported. We should get an empty
+ // error code and the expected permissions.
+ const auto expected_link_perms = TC.expected;
+ std::error_code expected_ec;
+#else
+ // On linux symlink permissions are not supported. The error code should
+ // be 'operation_not_supported' and the sylink permissions should be
+ // unchanged.
+ const auto expected_link_perms = symlink_status(sym).permissions();
+ std::error_code expected_ec = std::make_error_code(std::errc::operation_not_supported);
+#endif
+ std::error_code ec = std::make_error_code(std::errc::bad_address);
+ permissions(sym, TC.set_perms, ec);
+ TEST_CHECK(ec == expected_ec);
+ TEST_CHECK(status(file).permissions() == file_perms);
+ TEST_CHECK(symlink_status(sym).permissions() == expected_link_perms);
+ }
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp
new file mode 100644
index 00000000000..00581cbe8bc
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.read_symlink/read_symlink.pass.cpp
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// path read_symlink(const path& p);
+// path read_symlink(const path& p, error_code& ec);
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_read_symlink_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::read_symlink(p)), fs::path);
+ ASSERT_SAME_TYPE(decltype(fs::read_symlink(p, ec)), fs::path);
+
+ ASSERT_NOT_NOEXCEPT(fs::read_symlink(p));
+ // Not noexcept because of narrow contract
+ ASSERT_NOT_NOEXCEPT(fs::read_symlink(p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::read_symlink(f);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == ""
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+
+ scoped_test_env env;
+ const path cases[] = {
+ env.make_env_path("dne"),
+ env.create_file("file", 42),
+ env.create_dir("dir")
+ };
+ for (path const& p : cases) {
+ std::error_code ec;
+ const path ret = fs::read_symlink(p, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(ret == path{});
+ TEST_CHECK(checkThrow(p, ec));
+ }
+
+}
+
+TEST_CASE(basic_symlink_test)
+{
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path file = env.create_file("file", 42);
+ const path dir = env.create_dir("dir");
+ const path link = env.create_symlink(dne, "link");
+ const path nested_link = env.make_env_path("nested_link");
+ create_symlink(link, nested_link);
+ struct TestCase {
+ path symlink;
+ path expected;
+ } testCases[] = {
+ {env.create_symlink(dne, "dne_link"), dne},
+ {env.create_symlink(file, "file_link"), file},
+ {env.create_symlink(dir, "dir_link"), dir},
+ {nested_link, link}
+ };
+ for (auto& TC : testCases) {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ const path ret = read_symlink(TC.symlink, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(ret == TC.expected);
+ }
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp
new file mode 100644
index 00000000000..edb0c4fc76c
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove/remove.pass.cpp
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool remove(const path& p);
+// bool remove(const path& p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_remove_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::remove(p)), bool);
+ ASSERT_SAME_TYPE(decltype(fs::remove(p, ec)), bool);
+
+ ASSERT_NOT_NOEXCEPT(fs::remove(p));
+ ASSERT_NOEXCEPT(fs::remove(p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::remove(f);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == ""
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+ scoped_test_env env;
+ const path non_empty_dir = env.create_dir("dir");
+ env.create_file(non_empty_dir / "file1", 42);
+ const path bad_perms_dir = env.create_dir("bad_dir");
+ const path file_in_bad_dir = env.create_file(bad_perms_dir / "file", 42);
+ permissions(bad_perms_dir, perms::none);
+ const path testCases[] = {
+ "",
+ env.make_env_path("dne"),
+ non_empty_dir,
+ file_in_bad_dir,
+ };
+ for (auto& p : testCases) {
+ std::error_code ec;
+ TEST_CHECK(!fs::remove(p, ec));
+ TEST_CHECK(ec);
+ TEST_CHECK(checkThrow(p, ec));
+ }
+}
+
+TEST_CASE(basic_remove_test)
+{
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path link = env.create_symlink(dne, "link");
+ const path nested_link = env.make_env_path("nested_link");
+ create_symlink(link, nested_link);
+ const path testCases[] = {
+ env.create_file("file", 42),
+ env.create_dir("empty_dir"),
+ nested_link,
+ link
+ };
+ for (auto& p : testCases) {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ TEST_CHECK(remove(p, ec));
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(symlink_status(p)));
+ }
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp
new file mode 100644
index 00000000000..aecfce7885e
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp
@@ -0,0 +1,141 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// uintmax_t remove_all(const path& p);
+// uintmax_t remove_all(const path& p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_remove_all_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::remove_all(p)), std::uintmax_t);
+ ASSERT_SAME_TYPE(decltype(fs::remove_all(p, ec)), std::uintmax_t);
+
+ ASSERT_NOT_NOEXCEPT(fs::remove_all(p));
+ ASSERT_NOEXCEPT(fs::remove_all(p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::remove_all(f);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == ""
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+ scoped_test_env env;
+ const path non_empty_dir = env.create_dir("dir");
+ env.create_file(non_empty_dir / "file1", 42);
+ const path bad_perms_dir = env.create_dir("bad_dir");
+ const path file_in_bad_dir = env.create_file(bad_perms_dir / "file", 42);
+ permissions(bad_perms_dir, perms::none);
+ const path bad_perms_file = env.create_file("file2", 42);
+ permissions(bad_perms_file, perms::none);
+
+ const path testCases[] = {
+ env.make_env_path("dne"),
+ file_in_bad_dir
+ };
+ const auto BadRet = static_cast<std::uintmax_t>(-1);
+ for (auto& p : testCases) {
+ std::error_code ec;
+ TEST_CHECK(fs::remove_all(p, ec) == BadRet);
+ TEST_CHECK(ec);
+ TEST_CHECK(checkThrow(p, ec));
+ }
+}
+
+TEST_CASE(basic_remove_all_test)
+{
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path link = env.create_symlink(dne, "link");
+ const path nested_link = env.make_env_path("nested_link");
+ create_symlink(link, nested_link);
+ const path testCases[] = {
+ env.create_file("file", 42),
+ env.create_dir("empty_dir"),
+ nested_link,
+ link
+ };
+ for (auto& p : testCases) {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ TEST_CHECK(remove(p, ec));
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(symlink_status(p)));
+ }
+}
+
+TEST_CASE(symlink_to_dir)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file(dir / "file", 42);
+ const path link = env.create_symlink(dir, "sym");
+
+ {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ TEST_CHECK(remove_all(link, ec) == 1);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(symlink_status(link)));
+ TEST_CHECK(exists(dir));
+ TEST_CHECK(exists(file));
+ }
+}
+
+
+TEST_CASE(nested_dir)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path dir1 = env.create_dir(dir / "dir1");
+ const path out_of_dir_file = env.create_file("file1", 42);
+ const path all_files[] = {
+ dir, dir1,
+ env.create_file(dir / "file1", 42),
+ env.create_symlink(out_of_dir_file, dir / "sym1"),
+ env.create_file(dir1 / "file2", 42),
+ env.create_symlink(dir, dir1 / "sym2")
+ };
+ const std::size_t expected_count = sizeof(all_files) / sizeof(all_files[0]);
+
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ TEST_CHECK(remove_all(dir, ec) == expected_count);
+ TEST_CHECK(!ec);
+ for (auto const& p : all_files) {
+ TEST_CHECK(!exists(symlink_status(p)));
+ }
+ TEST_CHECK(exists(out_of_dir_file));
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp
new file mode 100644
index 00000000000..c2ae854c0bf
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.rename/rename.pass.cpp
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// void rename(const path& old_p, const path& new_p);
+// void rename(const path& old_p, const path& new_p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_rename_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(fs::rename(p, p)), void);
+ ASSERT_SAME_TYPE(decltype(fs::rename(p, p, ec)), void);
+
+ ASSERT_NOT_NOEXCEPT(fs::rename(p, p));
+ ASSERT_NOEXCEPT(fs::rename(p, p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::rename(f, t);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == t
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path file = env.create_file("file1", 42);
+ const path dir = env.create_dir("dir1");
+ struct TestCase {
+ path from;
+ path to;
+ } cases[] = {
+ {dne, dne},
+ {file, dir},
+ {dir, file}
+ };
+ for (auto& TC : cases) {
+ auto from_before = status(TC.from);
+ auto to_before = status(TC.to);
+ std::error_code ec;
+ rename(TC.from, TC.to, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(from_before.type() == status(TC.from).type());
+ TEST_CHECK(to_before.type() == status(TC.to).type());
+ TEST_CHECK(checkThrow(TC.from, TC.to, ec));
+ }
+}
+
+TEST_CASE(basic_rename_test)
+{
+ scoped_test_env env;
+
+ const std::error_code set_ec = std::make_error_code(std::errc::address_in_use);
+ const path file = env.create_file("file1", 42);
+ { // same file
+ std::error_code ec = set_ec;
+ rename(file, file, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(is_regular_file(file));
+ TEST_CHECK(file_size(file) == 42);
+ }
+ const path sym = env.create_symlink(file, "sym");
+ { // file -> symlink
+ std::error_code ec = set_ec;
+ rename(file, sym, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(file));
+ TEST_CHECK(is_regular_file(symlink_status(sym)));
+ TEST_CHECK(file_size(sym) == 42);
+ }
+ const path file2 = env.create_file("file2", 42);
+ const path file3 = env.create_file("file3", 100);
+ { // file -> file
+ std::error_code ec = set_ec;
+ rename(file2, file3, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(file2));
+ TEST_CHECK(is_regular_file(file3));
+ TEST_CHECK(file_size(file3) == 42);
+ }
+ const path dne = env.make_env_path("dne");
+ const path bad_sym = env.create_symlink(dne, "bad_sym");
+ const path bad_sym_dest = env.make_env_path("bad_sym2");
+ { // bad-symlink
+ std::error_code ec = set_ec;
+ rename(bad_sym, bad_sym_dest, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(!exists(symlink_status(bad_sym)));
+ TEST_CHECK(is_symlink(bad_sym_dest));
+ TEST_CHECK(read_symlink(bad_sym_dest) == dne);
+ }
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp
new file mode 100644
index 00000000000..8a6aa09b14c
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.resize_file/resize_file.pass.cpp
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// void resize_file(const path& p, uintmax_t new_size);
+// void resize_file(const path& p, uintmax_t new_size, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+namespace fs = std::experimental::filesystem;
+
+TEST_SUITE(filesystem_resize_file_test_suite)
+
+TEST_CASE(test_signatures)
+{
+ const path p; ((void)p);
+ std::uintmax_t i; ((void)i);
+ std::error_code ec; ((void)ec);
+
+ ASSERT_SAME_TYPE(decltype(fs::resize_file(p, i)), void);
+ ASSERT_SAME_TYPE(decltype(fs::resize_file(p, i, ec)), void);
+
+ ASSERT_NOT_NOEXCEPT(fs::resize_file(p, i));
+ ASSERT_NOEXCEPT(fs::resize_file(p, i, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, std::uintmax_t s, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ fs::resize_file(f, s);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == ""
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path bad_sym = env.create_symlink(dne, "sym");
+ const path dir = env.create_dir("dir1");
+ const path cases[] = {
+ dne, bad_sym, dir
+ };
+ for (auto& p : cases) {
+ std::error_code ec;
+ resize_file(p, 42, ec);
+ TEST_REQUIRE(ec);
+ TEST_CHECK(checkThrow(p, 42, ec));
+ }
+}
+
+TEST_CASE(basic_resize_file_test)
+{
+ scoped_test_env env;
+ const path file1 = env.create_file("file1", 42);
+ const auto set_ec = std::make_error_code(std::errc::address_in_use);
+ { // grow file
+ const std::uintmax_t new_s = 100;
+ std::error_code ec = set_ec;
+ resize_file(file1, new_s, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(file1) == new_s);
+ }
+ { // shrink file
+ const std::uintmax_t new_s = 1;
+ std::error_code ec = set_ec;
+ resize_file(file1, new_s, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(file1) == new_s);
+ }
+ { // shrink file to zero
+ const std::uintmax_t new_s = 0;
+ std::error_code ec = set_ec;
+ resize_file(file1, new_s, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(file1) == new_s);
+ }
+ const path sym = env.create_symlink(file1, "sym");
+ { // grow file via symlink
+ const std::uintmax_t new_s = 1024;
+ std::error_code ec = set_ec;
+ resize_file(sym, new_s, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(file_size(file1) == new_s);
+ }
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp
new file mode 100644
index 00000000000..7082c9d121b
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.space/space.pass.cpp
@@ -0,0 +1,113 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// space_info space(const path& p);
+// space_info space(const path& p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+#include <sys/statvfs.h>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+bool EqualDelta(std::uintmax_t x, std::uintmax_t y, std::uintmax_t delta) {
+ if (x >= y) {
+ return (x - y) <= delta;
+ } else {
+ return (y - x) <= delta;
+ }
+}
+
+TEST_SUITE(filesystem_space_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_SAME_TYPE(decltype(space(p)), space_info);
+ ASSERT_SAME_TYPE(decltype(space(p, ec)), space_info);
+ ASSERT_NOT_NOEXCEPT(space(p));
+ ASSERT_NOEXCEPT(space(p, ec));
+}
+
+TEST_CASE(test_error_reporting)
+{
+ auto checkThrow = [](path const& f, const std::error_code& ec)
+ {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ space(f);
+ return false;
+ } catch (filesystem_error const& err) {
+ return err.path1() == f
+ && err.path2() == ""
+ && err.code() == ec;
+ }
+#else
+ return true;
+#endif
+ };
+ const path cases[] = {
+ "",
+ StaticEnv::DNE,
+ StaticEnv::BadSymlink
+ };
+ for (auto& p : cases) {
+ const auto expect = static_cast<std::uintmax_t>(-1);
+ std::error_code ec;
+ space_info info = space(p, ec);
+ TEST_CHECK(ec);
+ TEST_CHECK(info.capacity == expect);
+ TEST_CHECK(info.free == expect);
+ TEST_CHECK(info.available == expect);
+ TEST_CHECK(checkThrow(p, ec));
+ }
+}
+
+TEST_CASE(basic_space_test)
+{
+ // All the test cases should reside on the same filesystem and therefore
+ // should have the same expected result. Compute this expected result
+ // one and check that it looks semi-sane.
+ struct statvfs expect;
+ TEST_REQUIRE(::statvfs(StaticEnv::Dir.c_str(), &expect) != -1);
+ TEST_CHECK(expect.f_bavail > 0);
+ TEST_CHECK(expect.f_bfree > 0);
+ TEST_CHECK(expect.f_bsize > 0);
+ TEST_CHECK(expect.f_blocks > 0);
+ const std::uintmax_t expect_cap = expect.f_blocks * expect.f_frsize;
+ // Other processes running on the operating system may have changed
+ // the amount of space available. Check that these are within tolerances.
+ // Currently 5% of capacity
+ const std::uintmax_t delta = expect_cap / 20;
+ const path cases[] = {
+ StaticEnv::File,
+ StaticEnv::Dir,
+ StaticEnv::Dir2,
+ StaticEnv::SymlinkToFile,
+ StaticEnv::SymlinkToDir
+ };
+ for (auto& p : cases) {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ space_info info = space(p, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK((expect.f_blocks * expect.f_frsize) == info.capacity);
+ TEST_CHECK(EqualDelta((expect.f_bfree * expect.f_frsize), info.free, delta));
+ TEST_CHECK(EqualDelta((expect.f_bavail * expect.f_frsize), info.available, delta));
+ }
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp
new file mode 100644
index 00000000000..2c76caf74c8
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.status/status.pass.cpp
@@ -0,0 +1,159 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// file_status status(const path& p);
+// file_status status(const path& p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(filesystem_status_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(status(p));
+ ASSERT_NOEXCEPT(status(p, ec));
+}
+
+TEST_CASE(test_status_not_found)
+{
+ const std::error_code expect_ec =
+ std::make_error_code(std::errc::no_such_file_or_directory);
+ const path cases[] {
+ StaticEnv::DNE,
+ StaticEnv::BadSymlink
+ };
+ for (auto& p : cases) {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ // test non-throwing overload.
+ file_status st = status(p, ec);
+ TEST_CHECK(ec == expect_ec);
+ TEST_CHECK(st.type() == file_type::not_found);
+ TEST_CHECK(st.permissions() == perms::unknown);
+ // test throwing overload. It should not throw even though it reports
+ // that the file was not found.
+ TEST_CHECK_NO_THROW(st = status(p));
+ TEST_CHECK(st.type() == file_type::not_found);
+ TEST_CHECK(st.permissions() == perms::unknown);
+ }
+}
+
+TEST_CASE(test_status_cannot_resolve)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+ const path sym = env.create_symlink("dir/file", "sym");
+ permissions(dir, perms::none);
+
+ const std::error_code set_ec =
+ std::make_error_code(std::errc::address_in_use);
+ const std::error_code expect_ec =
+ std::make_error_code(std::errc::permission_denied);
+
+ const path cases[] = {
+ file, sym
+ };
+ for (auto& p : cases)
+ {
+ { // test non-throwing case
+ std::error_code ec = set_ec;
+ file_status st = status(p, ec);
+ TEST_CHECK(ec == expect_ec);
+ TEST_CHECK(st.type() == file_type::none);
+ TEST_CHECK(st.permissions() == perms::unknown);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ { // test throwing case
+ try {
+ status(p);
+ } catch (filesystem_error const& err) {
+ TEST_CHECK(err.path1() == p);
+ TEST_CHECK(err.path2() == "");
+ TEST_CHECK(err.code() == expect_ec);
+ }
+ }
+#endif
+ }
+}
+
+TEST_CASE(status_file_types_test)
+{
+ scoped_test_env env;
+ struct TestCase {
+ path p;
+ file_type expect_type;
+ } cases[] = {
+ {StaticEnv::File, file_type::regular},
+ {StaticEnv::SymlinkToFile, file_type::regular},
+ {StaticEnv::Dir, file_type::directory},
+ {StaticEnv::SymlinkToDir, file_type::directory},
+ // Block files tested elsewhere
+ {StaticEnv::CharFile, file_type::character},
+#if !defined(__APPLE__) && !defined(__FreeBSD__) // No support for domain sockets
+ {env.create_socket("socket"), file_type::socket},
+#endif
+ {env.create_fifo("fifo"), file_type::fifo}
+ };
+ for (const auto& TC : cases) {
+ // test non-throwing case
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ file_status st = status(TC.p, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(st.type() == TC.expect_type);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ // test throwing case
+ TEST_REQUIRE_NO_THROW(st = status(TC.p));
+ TEST_CHECK(st.type() == TC.expect_type);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ }
+}
+
+TEST_CASE(test_block_file)
+{
+ const path possible_paths[] = {
+ "/dev/drive0", // Apple
+ "/dev/sda",
+ "/dev/loop0"
+ };
+ path p;
+ for (const path& possible_p : possible_paths) {
+ std::error_code ec;
+ if (exists(possible_p, ec)) {
+ p = possible_p;
+ break;
+ }
+ }
+ if (p == path{}) {
+ TEST_UNSUPPORTED();
+ }
+ // test non-throwing case
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ file_status st = status(p, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(st.type() == file_type::block);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ // test throwing case
+ TEST_REQUIRE_NO_THROW(st = status(p));
+ TEST_CHECK(st.type() == file_type::block);
+ TEST_CHECK(st.permissions() != perms::unknown);
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp
new file mode 100644
index 00000000000..169c5be9d9a
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.status_known/status_known.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// bool status_known(file_status s) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(status_known_test_suite)
+
+TEST_CASE(signature_test)
+{
+ file_status s; ((void)s);
+ ASSERT_SAME_TYPE(decltype(status_known(s)), bool);
+ ASSERT_NOEXCEPT(status_known(s));
+}
+
+TEST_CASE(status_known_test)
+{
+ struct TestCase {
+ file_type type;
+ bool expect;
+ };
+ const TestCase testCases[] = {
+ {file_type::none, false},
+ {file_type::not_found, true},
+ {file_type::regular, true},
+ {file_type::directory, true},
+ {file_type::symlink, true},
+ {file_type::block, true},
+ {file_type::character, true},
+ {file_type::fifo, true},
+ {file_type::socket, true},
+ {file_type::unknown, true}
+ };
+ for (auto& TC : testCases) {
+ file_status s(TC.type);
+ TEST_CHECK(status_known(s) == TC.expect);
+ }
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp
new file mode 100644
index 00000000000..647504f6e1a
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp
@@ -0,0 +1,192 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// file_status symlink_status(const path& p);
+// file_status symlink_status(const path& p, error_code& ec) noexcept;
+
+#include <experimental/filesystem>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(filesystem_symlink_status_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(symlink_status(p));
+ ASSERT_NOEXCEPT(symlink_status(p, ec));
+}
+
+TEST_CASE(test_symlink_status_not_found)
+{
+ const std::error_code expect_ec =
+ std::make_error_code(std::errc::no_such_file_or_directory);
+ const path cases[] {
+ StaticEnv::DNE
+ };
+ for (auto& p : cases) {
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ // test non-throwing overload.
+ file_status st = symlink_status(p, ec);
+ TEST_CHECK(ec == expect_ec);
+ TEST_CHECK(st.type() == file_type::not_found);
+ TEST_CHECK(st.permissions() == perms::unknown);
+ // test throwing overload. It should not throw even though it reports
+ // that the file was not found.
+ TEST_CHECK_NO_THROW(st = status(p));
+ TEST_CHECK(st.type() == file_type::not_found);
+ TEST_CHECK(st.permissions() == perms::unknown);
+ }
+}
+
+TEST_CASE(test_symlink_status_cannot_resolve)
+{
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file_in_dir = env.create_file("dir/file", 42);
+ const path sym_in_dir = env.create_symlink("dir/file", "dir/bad_sym");
+ const path sym_points_in_dir = env.create_symlink("dir/file", "sym");
+ permissions(dir, perms::none);
+
+ const std::error_code set_ec =
+ std::make_error_code(std::errc::address_in_use);
+ const std::error_code expect_ec =
+ std::make_error_code(std::errc::permission_denied);
+
+ const path fail_cases[] = {
+ file_in_dir, sym_in_dir
+ };
+ for (auto& p : fail_cases)
+ {
+ { // test non-throwing case
+ std::error_code ec = set_ec;
+ file_status st = symlink_status(p, ec);
+ TEST_CHECK(ec == expect_ec);
+ TEST_CHECK(st.type() == file_type::none);
+ TEST_CHECK(st.permissions() == perms::unknown);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ { // test throwing case
+ try {
+ symlink_status(p);
+ } catch (filesystem_error const& err) {
+ TEST_CHECK(err.path1() == p);
+ TEST_CHECK(err.path2() == "");
+ TEST_CHECK(err.code() == expect_ec);
+ }
+ }
+#endif
+ }
+ // Test that a symlink that points into a directory without read perms
+ // can be stat-ed using symlink_status
+ {
+ std::error_code ec = set_ec;
+ file_status st = symlink_status(sym_points_in_dir, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(st.type() == file_type::symlink);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ // test non-throwing version
+ TEST_REQUIRE_NO_THROW(st = symlink_status(sym_points_in_dir));
+ TEST_CHECK(st.type() == file_type::symlink);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ }
+}
+
+
+TEST_CASE(symlink_status_file_types_test)
+{
+ scoped_test_env env;
+ struct TestCase {
+ path p;
+ file_type expect_type;
+ } cases[] = {
+ {StaticEnv::BadSymlink, file_type::symlink},
+ {StaticEnv::File, file_type::regular},
+ {StaticEnv::SymlinkToFile, file_type::symlink},
+ {StaticEnv::Dir, file_type::directory},
+ {StaticEnv::SymlinkToDir, file_type::symlink},
+ // Block files tested elsewhere
+ {StaticEnv::CharFile, file_type::character},
+#if !defined(__APPLE__) && !defined(__FreeBSD__) // No support for domain sockets
+ {env.create_socket("socket"), file_type::socket},
+#endif
+ {env.create_fifo("fifo"), file_type::fifo}
+ };
+ for (const auto& TC : cases) {
+ // test non-throwing case
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ file_status st = symlink_status(TC.p, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(st.type() == TC.expect_type);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ // test throwing case
+ TEST_REQUIRE_NO_THROW(st = symlink_status(TC.p));
+ TEST_CHECK(st.type() == TC.expect_type);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ }
+}
+
+TEST_CASE(test_block_file)
+{
+ const path possible_paths[] = {
+ "/dev/drive0", // Apple
+ "/dev/sda", // Linux
+ "/dev/loop0" // Linux
+ // No FreeBSD files known
+ };
+ path p;
+ for (const path& possible_p : possible_paths) {
+ std::error_code ec;
+ if (exists(possible_p, ec)) {
+ p = possible_p;
+ break;
+ }
+ }
+ if (p == path{}) {
+ TEST_UNSUPPORTED();
+ }
+ scoped_test_env env;
+ { // test block file
+ // test non-throwing case
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ file_status st = symlink_status(p, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(st.type() == file_type::block);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ // test throwing case
+ TEST_REQUIRE_NO_THROW(st = symlink_status(p));
+ TEST_CHECK(st.type() == file_type::block);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ }
+ const path sym = env.make_env_path("sym");
+ create_symlink(p, sym);
+ { // test symlink to block file
+ // test non-throwing case
+ std::error_code ec = std::make_error_code(std::errc::address_in_use);
+ file_status st = symlink_status(sym, ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(st.type() == file_type::symlink);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ // test throwing case
+ TEST_REQUIRE_NO_THROW(st = symlink_status(sym));
+ TEST_CHECK(st.type() == file_type::symlink);
+ TEST_CHECK(st.permissions() != perms::unknown);
+ }
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp
new file mode 100644
index 00000000000..634184e24e6
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.system_complete/system_complete.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// path system_complete(const path& p);
+// path system_complete(const path& p, error_code& ec);
+
+// Note: For POSIX based operating systems, 'system_complete(p)' has the
+// same semantics as 'absolute(p, current_path())'.
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+TEST_SUITE(filesystem_system_complete_test_suite)
+
+TEST_CASE(signature_test)
+{
+ const path p; ((void)p);
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(system_complete(p));
+ ASSERT_NOT_NOEXCEPT(system_complete(p, ec));
+}
+
+
+TEST_CASE(basic_system_complete_tests)
+{
+ const path testCases[] = {
+ "//net/foo", // has_root_name() && has_root_directory()
+ "/foo", // !has_root_name() && has_root_directory()
+ "//net", // has_root_name() && !has_root_directory()
+ "bar/baz" // !has_root_name() && !has_root_directory()
+ };
+ const path base = current_path();
+ for (auto& p : testCases) {
+ const path ret = system_complete(p);
+ const path expect = absolute(p, base);
+ TEST_CHECK(ret.is_absolute());
+ TEST_CHECK(ret == expect);
+ }
+}
+
+TEST_SUITE_END()
diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp
new file mode 100644
index 00000000000..215c35a33f3
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp
@@ -0,0 +1,110 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// path temp_directory_path();
+// path temp_directory_path(error_code& ec);
+
+#include <experimental/filesystem>
+#include <memory>
+#include <cstdlib>
+#include <cstring>
+#include <cassert>
+
+#include "test_macros.h"
+#include "rapid-cxx-test.hpp"
+#include "filesystem_test_helper.hpp"
+
+using namespace std::experimental::filesystem;
+
+void PutEnv(std::string var, std::string value) {
+ assert(::setenv(var.c_str(), value.c_str(), /* overwrite */ 1) == 0);
+}
+
+void UnsetEnv(std::string var) {
+ assert(::unsetenv(var.c_str()) == 0);
+}
+
+TEST_SUITE(filesystem_temp_directory_path_test_suite)
+
+TEST_CASE(signature_test)
+{
+ std::error_code ec; ((void)ec);
+ ASSERT_NOT_NOEXCEPT(temp_directory_path());
+ ASSERT_NOT_NOEXCEPT(temp_directory_path(ec));
+}
+
+TEST_CASE(basic_tests)
+{
+ scoped_test_env env;
+ const path dne = env.make_env_path("dne");
+ const path file = env.create_file("file", 42);
+ const path dir_perms = env.create_dir("bad_perms_dir");
+ const path nested_dir = env.create_dir("bad_perms_dir/nested");
+ permissions(dir_perms, perms::none);
+ const std::error_code set_ec = std::make_error_code(std::errc::address_in_use);
+ const std::error_code expect_ec = std::make_error_code(std::errc::not_a_directory);
+ struct TestCase {
+ std::string name;
+ path p;
+ } cases[] = {
+ {"TMPDIR", env.create_dir("dir1")},
+ {"TMP", env.create_dir("dir2")},
+ {"TEMP", env.create_dir("dir3")},
+ {"TEMPDIR", env.create_dir("dir4")}
+ };
+ for (auto& TC : cases) {
+ PutEnv(TC.name, TC.p);
+ }
+ for (auto& TC : cases) {
+ std::error_code ec = set_ec;
+ path ret = temp_directory_path(ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(ret == TC.p);
+ TEST_CHECK(is_directory(ret));
+
+ // Set the env variable to a path that does not exist and check
+ // that it fails.
+ PutEnv(TC.name, dne);
+ ec = set_ec;
+ ret = temp_directory_path(ec);
+ TEST_CHECK(ec == expect_ec);
+ TEST_CHECK(ret == "");
+
+ // Set the env variable to point to a file and check that it fails.
+ PutEnv(TC.name, file);
+ ec = set_ec;
+ ret = temp_directory_path(ec);
+ TEST_CHECK(ec == expect_ec);
+ TEST_CHECK(ret == "");
+
+ // Set the env variable to point to a dir we can't access
+ PutEnv(TC.name, nested_dir);
+ ec = set_ec;
+ ret = temp_directory_path(ec);
+ TEST_CHECK(ec == std::make_error_code(std::errc::permission_denied));
+ TEST_CHECK(ret == "");
+
+ // Finally erase this env variable
+ UnsetEnv(TC.name);
+ }
+ // No env variables are defined
+ {
+ std::error_code ec = set_ec;
+ path ret = temp_directory_path(ec);
+ TEST_CHECK(!ec);
+ TEST_CHECK(ret == "/tmp");
+ TEST_CHECK(is_directory(ret));
+ }
+}
+
+TEST_SUITE_END()
OpenPOWER on IntegriCloud