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 // <filesystem>
13
14 // file_status status(const path& p);
15 // file_status status(const path& p, error_code& ec) noexcept;
16
17 #include "filesystem_include.hpp"
18
19 #include "test_macros.h"
20 #include "rapid-cxx-test.hpp"
21 #include "filesystem_test_helper.hpp"
22
23 using namespace fs;
24
25 TEST_SUITE(filesystem_status_test_suite)
26
TEST_CASE(signature_test)27 TEST_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
TEST_CASE(test_status_not_found)35 TEST_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
TEST_CASE(test_status_cannot_resolve)58 TEST_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
TEST_CASE(status_file_types_test)104 TEST_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
TEST_CASE(test_block_file)136 TEST_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
166 TEST_SUITE_END()
167