16e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#ifndef FILESYSTEM_TEST_HELPER_HPP 26e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#define FILESYSTEM_TEST_HELPER_HPP 36e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 46e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include <experimental/filesystem> 56e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include <cassert> 66e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include <cstdio> // for printf 76e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include <string> 86e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include <fstream> 96e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include <random> 1040d9e09d892af387d97a8ab507f440ff027cd206Eric Fiselier#include <chrono> 116e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 126e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliernamespace fs = std::experimental::filesystem; 136e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 146e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// static test helpers 156e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 166e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#ifndef LIBCXX_FILESYSTEM_STATIC_TEST_ROOT 176e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#warning "STATIC TESTS DISABLED" 186e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#else // LIBCXX_FILESYSTEM_STATIC_TEST_ROOT 196e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 206e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliernamespace StaticEnv { 216e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 226e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierinline fs::path makePath(fs::path const& p) { 23374a33d1b9a9808c3f641867bb5e68a8e93bd9caEric Fiselier // env_path is expected not to contain symlinks. 246e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static const fs::path env_path = LIBCXX_FILESYSTEM_STATIC_TEST_ROOT; 256e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return env_path / p; 266e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 276e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 286e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path Root = LIBCXX_FILESYSTEM_STATIC_TEST_ROOT; 296e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 306e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path TestFileList[] = { 316e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("empty_file"), 326e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("non_empty_file"), 336e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/file1"), 346e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/file2") 356e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier}; 366e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierconst std::size_t TestFileListSize = sizeof(TestFileList) / sizeof(fs::path); 376e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 386e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path TestDirList[] = { 396e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1"), 406e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2"), 416e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/dir3") 426e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier}; 436e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierconst std::size_t TestDirListSize = sizeof(TestDirList) / sizeof(fs::path); 446e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 456e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path File = TestFileList[0]; 466e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path Dir = TestDirList[0]; 476e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path Dir2 = TestDirList[1]; 486e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path Dir3 = TestDirList[2]; 496e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path SymlinkToFile = makePath("symlink_to_empty_file"); 506e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path SymlinkToDir = makePath("symlink_to_dir"); 516e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path BadSymlink = makePath("bad_symlink"); 526e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path DNE = makePath("DNE"); 536e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path EmptyFile = TestFileList[0]; 546e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path NonEmptyFile = TestFileList[1]; 556e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path CharFile = "/dev/null"; // Hopefully this exists 566e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 576e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path DirIterationList[] = { 586e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2"), 596e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/file1"), 606e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/file2") 616e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier}; 626e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierconst std::size_t DirIterationListSize = sizeof(DirIterationList) 636e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier / sizeof(fs::path); 646e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 656e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path DirIterationListDepth1[] = { 666e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/afile3"), 676e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/dir3"), 686e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/symlink_to_dir3"), 696e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/file4"), 706e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier}; 716e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 726e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path RecDirIterationList[] = { 736e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2"), 746e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/file1"), 756e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/file2"), 766e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/afile3"), 776e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/dir3"), 786e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/symlink_to_dir3"), 796e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/file4"), 806e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/dir3/file5") 816e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier}; 826e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 836e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstatic const fs::path RecDirFollowSymlinksIterationList[] = { 846e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2"), 856e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/file1"), 866e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/file2"), 876e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/afile3"), 886e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/dir3"), 896e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/file4"), 906e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/dir3/file5"), 916e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/symlink_to_dir3"), 926e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier makePath("dir1/dir2/symlink_to_dir3/file5"), 936e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier}; 946e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 956e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} // namespace StaticEnv 966e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 976e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#endif // LIBCXX_FILESYSTEM_STATIC_TEST_ROOT 986e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 996e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#ifndef LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT 1006e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#warning LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT must be defined 1016e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#else // LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT 1026e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1036e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#ifndef LIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER 1046e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#error LIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER must be defined 1056e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#endif 1066e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1076e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstruct scoped_test_env 1086e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 1096e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier scoped_test_env() : test_root(random_env_path()) 1106e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier { fs_helper_run(fs_make_cmd("init_test_directory", test_root)); } 1116e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1126e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ~scoped_test_env() 1136e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier { fs_helper_run(fs_make_cmd("destroy_test_directory", test_root)); } 1146e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1156e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier scoped_test_env(scoped_test_env const &) = delete; 1166e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier scoped_test_env & operator=(scoped_test_env const &) = delete; 1176e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1186e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier fs::path make_env_path(std::string p) { return sanitize_path(p); } 1196e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1206e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::string sanitize_path(std::string raw) { 1216e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier assert(raw.find("..") == std::string::npos); 1226e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::string const& root = test_root.native(); 1236e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (root.compare(0, root.size(), raw, 0, root.size()) != 0) { 1246e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier assert(raw.front() != '\\'); 1256e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier fs::path tmp(test_root); 1266e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier tmp /= raw; 1276e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return std::move(const_cast<std::string&>(tmp.native())); 1286e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1296e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return raw; 1306e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1316e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1326e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::string create_file(std::string filename, std::size_t size = 0) { 1336e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier filename = sanitize_path(std::move(filename)); 1346e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::string out_str(size, 'a'); 1356e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier { 1366e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::ofstream out(filename.c_str()); 1376e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier out << out_str; 1386e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1396e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return filename; 1406e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1416e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1426e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::string create_dir(std::string filename) { 1436e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier filename = sanitize_path(std::move(filename)); 1446e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier fs_helper_run(fs_make_cmd("create_dir", filename)); 1456e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return filename; 1466e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1476e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1486e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::string create_symlink(std::string source, std::string to) { 1496e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier source = sanitize_path(std::move(source)); 1506e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier to = sanitize_path(std::move(to)); 1516e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier fs_helper_run(fs_make_cmd("create_symlink", source, to)); 1526e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return to; 1536e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1546e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1556e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::string create_hardlink(std::string source, std::string to) { 1566e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier source = sanitize_path(std::move(source)); 1576e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier to = sanitize_path(std::move(to)); 1586e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier fs_helper_run(fs_make_cmd("create_hardlink", source, to)); 1596e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return to; 1606e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1616e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1626e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::string create_fifo(std::string file) { 1636e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier file = sanitize_path(std::move(file)); 1646e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier fs_helper_run(fs_make_cmd("create_fifo", file)); 1656e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return file; 1666e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1676e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1686e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // OS X and FreeBSD doesn't support socket files so we shouldn't even 1696e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // allow tests to call this unguarded. 1706e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#if !defined(__FreeBSD__) && !defined(__APPLE__) 1716e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::string create_socket(std::string file) { 1726e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier file = sanitize_path(std::move(file)); 1736e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier fs_helper_run(fs_make_cmd("create_socket", file)); 1746e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return file; 1756e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1766e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#endif 1776e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1786e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier fs::path const test_root; 1796e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1806e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierprivate: 1816e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static char to_hex(int ch) { 1826e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return ch < 10 ? static_cast<char>('0' + ch) 1836e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier : static_cast<char>('a' + (ch - 10)); 1846e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1856e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1866e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static char random_hex_char() { 1876e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static std::mt19937 rd { std::random_device{}() }; 1886e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static std::uniform_int_distribution<int> mrand{0, 15}; 1896e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return to_hex( mrand(rd) ); 1906e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1916e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1926e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static std::string unique_path_suffix() { 1936e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::string model = "test.%%%%%%"; 1946e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier for (auto & ch : model) { 1956e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ch == '%') ch = random_hex_char(); 1966e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1976e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return model; 1986e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1996e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2006e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // This could potentially introduce a filesystem race with other tests 2016e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // running at the same time, but oh well, it's just test code. 2026e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static inline fs::path random_env_path() { 2036e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static const char* env_path = LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT; 2046e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier fs::path p = fs::path(env_path) / unique_path_suffix(); 2056e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier assert(p.parent_path() == env_path); 2066e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return p; 2076e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2086e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2096e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static inline std::string make_arg(std::string const& arg) { 2106e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return "'" + arg + "'"; 2116e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2126e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2136e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static inline std::string make_arg(std::size_t arg) { 2146e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return std::to_string(arg); 2156e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2166e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2176e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier template <class T> 2186e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static inline std::string 2196e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier fs_make_cmd(std::string const& cmd_name, T const& arg) { 2206e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return cmd_name + "(" + make_arg(arg) + ")"; 2216e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2226e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2236e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier template <class T, class U> 2246e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static inline std::string 2256e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier fs_make_cmd(std::string const& cmd_name, T const& arg1, U const& arg2) { 2266e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return cmd_name + "(" + make_arg(arg1) + ", " + make_arg(arg2) + ")"; 2276e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2286e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2296e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static inline void fs_helper_run(std::string const& raw_cmd) { 2306e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // check that the fs test root in the enviroment matches what we were 2316e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // compiled with. 2326e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static bool checked = checkDynamicTestRoot(); 2330e5ebbc77c3c2cfd7d835fcfe40fcb65df0c5598Eric Fiselier ((void)checked); 2346e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::string cmd = LIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER; 2356e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier cmd += " \"" + raw_cmd + "\""; 2366e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier int ret = std::system(cmd.c_str()); 2376e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier assert(ret == 0); 2386e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2396e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2406e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static bool checkDynamicTestRoot() { 241374a33d1b9a9808c3f641867bb5e68a8e93bd9caEric Fiselier // LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT is expected not to contain symlinks. 2426e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier char* fs_root = std::getenv("LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT"); 2436e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (!fs_root) { 2446e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::printf("ERROR: LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT must be a defined " 2456e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier "environment variable when running the test.\n"); 2466e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::abort(); 2476e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2486e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (std::string(fs_root) != LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT) { 2496e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::printf("ERROR: LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT enviroment variable" 2506e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier " must have the same value as when the test was compiled.\n"); 2516e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::printf(" Current Value: '%s'\n", fs_root); 2526e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::printf(" Expected Value: '%s'\n", LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT); 2536e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::abort(); 2546e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2556e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return true; 2566e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2576e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2586e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier}; 2596e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2606e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#endif // LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT 2616e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2626e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// Misc test types 2636e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2646e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#define CONCAT2(LHS, RHS) LHS##RHS 2656e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#define CONCAT(LHS, RHS) CONCAT2(LHS, RHS) 2666e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#define MKSTR(Str) {Str, CONCAT(L, Str), CONCAT(u, Str), CONCAT(U, Str)} 2676e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2686e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstruct MultiStringType { 2696e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const char* s; 2706e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const wchar_t* w; 2716e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const char16_t* u16; 2726e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const char32_t* u32; 2736e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2746e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier operator const char* () const { return s; } 2756e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier operator const wchar_t* () const { return w; } 2766e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier operator const char16_t* () const { return u16; } 2776e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier operator const char32_t* () const { return u32; } 2786e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier}; 2796e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2806e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierconst MultiStringType PathList[] = { 2816e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR(""), 2826e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR(" "), 2836e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("//"), 2846e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("."), 2856e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR(".."), 2866e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("foo"), 2876e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("/"), 2886e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("/foo"), 2896e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("foo/"), 2906e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("/foo/"), 2916e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("foo/bar"), 2926e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("/foo/bar"), 2936e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("//net"), 2946e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("//net/foo"), 2956e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("///foo///"), 2966e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("///foo///bar"), 2976e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("/."), 2986e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("./"), 2996e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("/.."), 3006e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("../"), 3016e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("foo/."), 3026e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("foo/.."), 3036e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("foo/./"), 3046e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("foo/./bar"), 3056e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("foo/../"), 3066e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("foo/../bar"), 3076e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:"), 3086e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:/"), 3096e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:foo"), 3106e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:/foo"), 3116e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:foo/"), 3126e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:/foo/"), 3136e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:/foo/bar"), 3146e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("prn:"), 3156e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:\\"), 3166e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:\\foo"), 3176e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:foo\\"), 3186e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:\\foo\\"), 3196e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:\\foo/"), 3206e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("c:/foo\\bar"), 3216e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("//"), 3226e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier MKSTR("/finally/we/need/one/really/really/really/really/really/really/really/long/string") 3236e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier}; 3246e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierconst unsigned PathListSize = sizeof(PathList) / sizeof(MultiStringType); 3256e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 3266e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliertemplate <class Iter> 3276e9a694dce70319e60dbdfb09cf055bacb4c948eEric FiselierIter IterEnd(Iter B) { 3286e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier using VT = typename std::iterator_traits<Iter>::value_type; 3296e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier for (; *B != VT{}; ++B) 3306e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ; 3316e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return B; 3326e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 3336e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 3346e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliertemplate <class CharT> 3356e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierconst CharT* StrEnd(CharT const* P) { 3366e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return IterEnd(P); 3376e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 3386e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 3396e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliertemplate <class CharT> 3406e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstd::size_t StrLen(CharT const* P) { 3416e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return StrEnd(P) - P; 3426e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 3436e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 3446e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// Testing the allocation behavior of the code_cvt functions requires 3456e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// *knowing* that the allocation was not done by "path::__str_". 3466e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// This hack forces path to allocate enough memory. 3476e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierinline void PathReserve(fs::path& p, std::size_t N) { 3486e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto const& native_ref = p.native(); 3496e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const_cast<std::string&>(native_ref).reserve(N); 3506e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 3516e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 3526e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliertemplate <class Iter1, class Iter2> 3536e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierbool checkCollectionsEqual( 3546e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier Iter1 start1, Iter1 const end1 3556e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier , Iter2 start2, Iter2 const end2 3566e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ) 3576e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 3586e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier while (start1 != end1 && start2 != end2) { 3596e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (*start1 != *start2) { 3606e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 3616e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3626e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ++start1; ++start2; 3636e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3646e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return (start1 == end1 && start2 == end2); 3656e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 3666e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 367880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier 368880e38b206ee452f777922dfa61a959cee0067cbEric Fiseliertemplate <class Iter1, class Iter2> 369880e38b206ee452f777922dfa61a959cee0067cbEric Fiselierbool checkCollectionsEqualBackwards( 370880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier Iter1 const start1, Iter1 end1 371880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier , Iter2 const start2, Iter2 end2 372880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier ) 373880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier{ 374880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier while (start1 != end1 && start2 != end2) { 375880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier --end1; --end2; 376880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier if (*end1 != *end2) { 377880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier return false; 378880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier } 379880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier } 380880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier return (start1 == end1 && start2 == end2); 381880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier} 382880e38b206ee452f777922dfa61a959cee0067cbEric Fiselier 3836e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// We often need to test that the error_code was cleared if no error occurs 38416e2ba19dfffdcf9bba202eb8a27fd79e3d15303Stephan T. Lavavej// this function returns an error_code which is set to an error that will 3856e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// never be returned by the filesystem functions. 3866e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierinline std::error_code GetTestEC() { 3876e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return std::make_error_code(std::errc::address_family_not_supported); 3886e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 3896e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 39040d9e09d892af387d97a8ab507f440ff027cd206Eric Fiselier// Provide our own Sleep routine since std::this_thread::sleep_for is not 39140d9e09d892af387d97a8ab507f440ff027cd206Eric Fiselier// available in single-threaded mode. 39240d9e09d892af387d97a8ab507f440ff027cd206Eric Fiseliervoid SleepFor(std::chrono::seconds dur) { 39340d9e09d892af387d97a8ab507f440ff027cd206Eric Fiselier using namespace std::chrono; 39429c26b91df36522bf83d4a5ceb37f75c32b360edEric Fiselier#if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) 39529c26b91df36522bf83d4a5ceb37f75c32b360edEric Fiselier using Clock = system_clock; 39629c26b91df36522bf83d4a5ceb37f75c32b360edEric Fiselier#else 39729c26b91df36522bf83d4a5ceb37f75c32b360edEric Fiselier using Clock = steady_clock; 39829c26b91df36522bf83d4a5ceb37f75c32b360edEric Fiselier#endif 39929c26b91df36522bf83d4a5ceb37f75c32b360edEric Fiselier const auto wake_time = Clock::now() + dur; 40029c26b91df36522bf83d4a5ceb37f75c32b360edEric Fiselier while (Clock::now() < wake_time) 40140d9e09d892af387d97a8ab507f440ff027cd206Eric Fiselier ; 40240d9e09d892af387d97a8ab507f440ff027cd206Eric Fiselier} 40340d9e09d892af387d97a8ab507f440ff027cd206Eric Fiselier 4046e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#endif /* FILESYSTEM_TEST_HELPER_HPP */ 405