• 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 // class directory_iterator
15 
16 //
17 // explicit recursive_directory_iterator(const path& p);
18 // recursive_directory_iterator(const path& p, directory_options options);
19 // recursive_directory_iterator(const path& p, error_code& ec);
20 // recursive_directory_iterator(const path& p, directory_options options, error_code& ec);
21 
22 
23 #include "filesystem_include.hpp"
24 #include <type_traits>
25 #include <set>
26 #include <cassert>
27 
28 #include "test_macros.h"
29 #include "rapid-cxx-test.hpp"
30 #include "filesystem_test_helper.hpp"
31 
32 using namespace fs;
33 
34 using RDI = recursive_directory_iterator;
35 
36 TEST_SUITE(recursive_directory_iterator_constructor_tests)
37 
TEST_CASE(test_constructor_signatures)38 TEST_CASE(test_constructor_signatures)
39 {
40     using D = recursive_directory_iterator;
41 
42     // explicit directory_iterator(path const&);
43     static_assert(!std::is_convertible<path, D>::value, "");
44     static_assert(std::is_constructible<D, path>::value, "");
45     static_assert(!std::is_nothrow_constructible<D, path>::value, "");
46 
47     // directory_iterator(path const&, error_code&)
48     static_assert(std::is_constructible<D, path,
49         std::error_code&>::value, "");
50     static_assert(!std::is_nothrow_constructible<D, path,
51         std::error_code&>::value, "");
52 
53     // directory_iterator(path const&, directory_options);
54     static_assert(std::is_constructible<D, path, directory_options>::value, "");
55     static_assert(!std::is_nothrow_constructible<D, path, directory_options>::value, "");
56 
57     // directory_iterator(path const&, directory_options, error_code&)
58     static_assert(std::is_constructible<D, path, directory_options, std::error_code&>::value, "");
59     static_assert(!std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, "");
60 }
61 
TEST_CASE(test_construction_from_bad_path)62 TEST_CASE(test_construction_from_bad_path)
63 {
64     std::error_code ec;
65     directory_options opts = directory_options::none;
66     const RDI endIt;
67 
68     const path testPaths[] = { StaticEnv::DNE, StaticEnv::BadSymlink };
69     for (path const& testPath : testPaths)
70     {
71         {
72             RDI it(testPath, ec);
73             TEST_CHECK(ec);
74             TEST_CHECK(it == endIt);
75         }
76         {
77             RDI it(testPath, opts, ec);
78             TEST_CHECK(ec);
79             TEST_CHECK(it == endIt);
80         }
81         {
82             TEST_CHECK_THROW(filesystem_error, RDI(testPath));
83             TEST_CHECK_THROW(filesystem_error, RDI(testPath, opts));
84         }
85     }
86 }
87 
TEST_CASE(access_denied_test_case)88 TEST_CASE(access_denied_test_case)
89 {
90     using namespace fs;
91     scoped_test_env env;
92     path const testDir = env.make_env_path("dir1");
93     path const testFile = testDir / "testFile";
94     env.create_dir(testDir);
95     env.create_file(testFile, 42);
96 
97     // Test that we can iterator over the directory before changing the perms
98     {
99         RDI it(testDir);
100         TEST_REQUIRE(it != RDI{});
101     }
102 
103     // Change the permissions so we can no longer iterate
104     permissions(testDir, perms::none);
105 
106     // Check that the construction fails when skip_permissions_denied is
107     // not given.
108     {
109         std::error_code ec;
110         RDI it(testDir, ec);
111         TEST_REQUIRE(ec);
112         TEST_CHECK(it == RDI{});
113     }
114     // Check that construction does not report an error when
115     // 'skip_permissions_denied' is given.
116     {
117         std::error_code ec;
118         RDI it(testDir, directory_options::skip_permission_denied, ec);
119         TEST_REQUIRE(!ec);
120         TEST_CHECK(it == RDI{});
121     }
122 }
123 
124 
TEST_CASE(access_denied_to_file_test_case)125 TEST_CASE(access_denied_to_file_test_case)
126 {
127     using namespace fs;
128     scoped_test_env env;
129     path const testFile = env.make_env_path("file1");
130     env.create_file(testFile, 42);
131 
132     // Change the permissions so we can no longer iterate
133     permissions(testFile, perms::none);
134 
135     // Check that the construction fails when skip_permissions_denied is
136     // not given.
137     {
138         std::error_code ec;
139         RDI it(testFile, ec);
140         TEST_REQUIRE(ec);
141         TEST_CHECK(it == RDI{});
142     }
143     // Check that construction still fails when 'skip_permissions_denied' is given
144     // because we tried to open a file and not a directory.
145     {
146         std::error_code ec;
147         RDI it(testFile, directory_options::skip_permission_denied, ec);
148         TEST_REQUIRE(ec);
149         TEST_CHECK(it == RDI{});
150     }
151 }
152 
TEST_CASE(test_open_on_empty_directory_equals_end)153 TEST_CASE(test_open_on_empty_directory_equals_end)
154 {
155     scoped_test_env env;
156     const path testDir = env.make_env_path("dir1");
157     env.create_dir(testDir);
158 
159     const RDI endIt;
160     {
161         std::error_code ec;
162         RDI it(testDir, ec);
163         TEST_CHECK(!ec);
164         TEST_CHECK(it == endIt);
165     }
166     {
167         RDI it(testDir);
168         TEST_CHECK(it == endIt);
169     }
170 }
171 
TEST_CASE(test_open_on_directory_succeeds)172 TEST_CASE(test_open_on_directory_succeeds)
173 {
174     const path testDir = StaticEnv::Dir;
175     std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList),
176                                 std::end(  StaticEnv::DirIterationList));
177     const RDI endIt{};
178 
179     {
180         std::error_code ec;
181         RDI it(testDir, ec);
182         TEST_REQUIRE(!ec);
183         TEST_CHECK(it != endIt);
184         TEST_CHECK(dir_contents.count(*it));
185     }
186     {
187         RDI it(testDir);
188         TEST_CHECK(it != endIt);
189         TEST_CHECK(dir_contents.count(*it));
190     }
191 }
192 
TEST_CASE(test_open_on_file_fails)193 TEST_CASE(test_open_on_file_fails)
194 {
195     const path testFile = StaticEnv::File;
196     const RDI endIt{};
197     {
198         std::error_code ec;
199         RDI it(testFile, ec);
200         TEST_REQUIRE(ec);
201         TEST_CHECK(it == endIt);
202     }
203     {
204         TEST_CHECK_THROW(filesystem_error, RDI(testFile));
205     }
206 }
207 
TEST_CASE(test_options_post_conditions)208 TEST_CASE(test_options_post_conditions)
209 {
210     const path goodDir = StaticEnv::Dir;
211     const path badDir = StaticEnv::DNE;
212 
213     {
214         std::error_code ec;
215 
216         RDI it1(goodDir, ec);
217         TEST_REQUIRE(!ec);
218         TEST_CHECK(it1.options() == directory_options::none);
219 
220         RDI it2(badDir, ec);
221         TEST_REQUIRE(ec);
222         TEST_REQUIRE(it2 == RDI{});
223     }
224     {
225         std::error_code ec;
226         const directory_options opts = directory_options::skip_permission_denied;
227 
228         RDI it1(goodDir, opts, ec);
229         TEST_REQUIRE(!ec);
230         TEST_CHECK(it1.options() == opts);
231 
232         RDI it2(badDir, opts, ec);
233         TEST_REQUIRE(ec);
234         TEST_REQUIRE(it2 == RDI{});
235     }
236     {
237         RDI it(goodDir);
238         TEST_CHECK(it.options() == directory_options::none);
239     }
240     {
241         const directory_options opts = directory_options::follow_directory_symlink;
242         RDI it(goodDir, opts);
243         TEST_CHECK(it.options() == opts);
244     }
245 }
246 TEST_SUITE_END()
247