1//===----------------------------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10// UNSUPPORTED: c++98, c++03 11 12// <experimental/filesystem> 13 14// file_status status(const path& p); 15// file_status status(const path& p, error_code& ec) noexcept; 16 17#include <experimental/filesystem> 18 19#include "test_macros.h" 20#include "rapid-cxx-test.hpp" 21#include "filesystem_test_helper.hpp" 22 23using namespace std::experimental::filesystem; 24 25TEST_SUITE(filesystem_status_test_suite) 26 27TEST_CASE(signature_test) 28{ 29 const path p; ((void)p); 30 std::error_code ec; ((void)ec); 31 ASSERT_NOT_NOEXCEPT(status(p)); 32 ASSERT_NOEXCEPT(status(p, ec)); 33} 34 35TEST_CASE(test_status_not_found) 36{ 37 const std::error_code expect_ec = 38 std::make_error_code(std::errc::no_such_file_or_directory); 39 const path cases[] { 40 StaticEnv::DNE, 41 StaticEnv::BadSymlink 42 }; 43 for (auto& p : cases) { 44 std::error_code ec = std::make_error_code(std::errc::address_in_use); 45 // test non-throwing overload. 46 file_status st = status(p, ec); 47 TEST_CHECK(ec == expect_ec); 48 TEST_CHECK(st.type() == file_type::not_found); 49 TEST_CHECK(st.permissions() == perms::unknown); 50 // test throwing overload. It should not throw even though it reports 51 // that the file was not found. 52 TEST_CHECK_NO_THROW(st = status(p)); 53 TEST_CHECK(st.type() == file_type::not_found); 54 TEST_CHECK(st.permissions() == perms::unknown); 55 } 56} 57 58TEST_CASE(test_status_cannot_resolve) 59{ 60 scoped_test_env env; 61 const path dir = env.create_dir("dir"); 62 const path file = env.create_file("dir/file", 42); 63 const path sym = env.create_symlink("dir/file", "sym"); 64 permissions(dir, perms::none); 65 66 const std::error_code set_ec = 67 std::make_error_code(std::errc::address_in_use); 68 const std::error_code perm_ec = 69 std::make_error_code(std::errc::permission_denied); 70 const std::error_code name_too_long_ec = 71 std::make_error_code(std::errc::filename_too_long); 72 73 struct TestCase { 74 path p; 75 std::error_code expect_ec; 76 } const TestCases[] = { 77 {file, perm_ec}, 78 {sym, perm_ec}, 79 {path(std::string(2500, 'a')), name_too_long_ec} 80 }; 81 for (auto& TC : TestCases) 82 { 83 { // test non-throwing case 84 std::error_code ec = set_ec; 85 file_status st = status(TC.p, ec); 86 TEST_CHECK(ec == TC.expect_ec); 87 TEST_CHECK(st.type() == file_type::none); 88 TEST_CHECK(st.permissions() == perms::unknown); 89 } 90#ifndef TEST_HAS_NO_EXCEPTIONS 91 { // test throwing case 92 try { 93 status(TC.p); 94 } catch (filesystem_error const& err) { 95 TEST_CHECK(err.path1() == TC.p); 96 TEST_CHECK(err.path2() == ""); 97 TEST_CHECK(err.code() == TC.expect_ec); 98 } 99 } 100#endif 101 } 102} 103 104TEST_CASE(status_file_types_test) 105{ 106 scoped_test_env env; 107 struct TestCase { 108 path p; 109 file_type expect_type; 110 } cases[] = { 111 {StaticEnv::File, file_type::regular}, 112 {StaticEnv::SymlinkToFile, file_type::regular}, 113 {StaticEnv::Dir, file_type::directory}, 114 {StaticEnv::SymlinkToDir, file_type::directory}, 115 // Block files tested elsewhere 116 {StaticEnv::CharFile, file_type::character}, 117#if !defined(__APPLE__) && !defined(__FreeBSD__) // No support for domain sockets 118 {env.create_socket("socket"), file_type::socket}, 119#endif 120 {env.create_fifo("fifo"), file_type::fifo} 121 }; 122 for (const auto& TC : cases) { 123 // test non-throwing case 124 std::error_code ec = std::make_error_code(std::errc::address_in_use); 125 file_status st = status(TC.p, ec); 126 TEST_CHECK(!ec); 127 TEST_CHECK(st.type() == TC.expect_type); 128 TEST_CHECK(st.permissions() != perms::unknown); 129 // test throwing case 130 TEST_REQUIRE_NO_THROW(st = status(TC.p)); 131 TEST_CHECK(st.type() == TC.expect_type); 132 TEST_CHECK(st.permissions() != perms::unknown); 133 } 134} 135 136TEST_CASE(test_block_file) 137{ 138 const path possible_paths[] = { 139 "/dev/drive0", // Apple 140 "/dev/sda", 141 "/dev/loop0" 142 }; 143 path p; 144 for (const path& possible_p : possible_paths) { 145 std::error_code ec; 146 if (exists(possible_p, ec)) { 147 p = possible_p; 148 break; 149 } 150 } 151 if (p == path{}) { 152 TEST_UNSUPPORTED(); 153 } 154 // test non-throwing case 155 std::error_code ec = std::make_error_code(std::errc::address_in_use); 156 file_status st = status(p, ec); 157 TEST_CHECK(!ec); 158 TEST_CHECK(st.type() == file_type::block); 159 TEST_CHECK(st.permissions() != perms::unknown); 160 // test throwing case 161 TEST_REQUIRE_NO_THROW(st = status(p)); 162 TEST_CHECK(st.type() == file_type::block); 163 TEST_CHECK(st.permissions() != perms::unknown); 164} 165 166TEST_SUITE_END() 167