• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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