37b26066774c8e3a947fb37b83dbb36c173fa2ff
[gcc.git] / libstdc++-v3 / testsuite / experimental / filesystem / iterators / recursive_directory_iterator.cc
1 // Copyright (C) 2015-2016 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
17
18 // { dg-options "-lstdc++fs" }
19 // { dg-do run { target c++11 } }
20 // { dg-require-filesystem-ts "" }
21
22 #include <experimental/filesystem>
23 #include <testsuite_hooks.h>
24 #include <testsuite_fs.h>
25
26 namespace fs = std::experimental::filesystem;
27
28 void
29 test01()
30 {
31 std::error_code ec;
32
33 // Test non-existent path.
34 const auto p = __gnu_test::nonexistent_path();
35 fs::recursive_directory_iterator iter(p, ec);
36 VERIFY( ec );
37 VERIFY( iter != fs::recursive_directory_iterator() );
38
39 // Test empty directory.
40 create_directory(p, fs::current_path(), ec);
41 VERIFY( !ec );
42 iter = fs::recursive_directory_iterator(p, ec);
43 VERIFY( !ec );
44 VERIFY( iter == fs::recursive_directory_iterator() );
45
46 // Test non-empty directory.
47 create_directories(p / "d1/d2");
48 VERIFY( !ec );
49 iter = fs::recursive_directory_iterator(p, ec);
50 VERIFY( !ec );
51 VERIFY( iter != fs::recursive_directory_iterator() );
52 VERIFY( iter->path() == p/"d1" );
53 ++iter;
54 VERIFY( iter->path() == p/"d1/d2" );
55 ++iter;
56 VERIFY( iter == fs::recursive_directory_iterator() );
57
58 // Test inaccessible directory.
59 permissions(p, fs::perms::none, ec);
60 VERIFY( !ec );
61 iter = fs::recursive_directory_iterator(p, ec);
62 VERIFY( ec );
63 VERIFY( iter != fs::recursive_directory_iterator() );
64
65 // Test inaccessible directory, skipping permission denied.
66 const auto opts = fs::directory_options::skip_permission_denied;
67 iter = fs::recursive_directory_iterator(p, opts, ec);
68 VERIFY( !ec );
69 VERIFY( iter == fs::recursive_directory_iterator() );
70
71 // Test inaccessible sub-directory.
72 permissions(p, fs::perms::owner_all, ec);
73 VERIFY( !ec );
74 permissions(p/"d1/d2", fs::perms::none, ec);
75 VERIFY( !ec );
76 iter = fs::recursive_directory_iterator(p, ec);
77 VERIFY( !ec );
78 VERIFY( iter != fs::recursive_directory_iterator() );
79 VERIFY( iter->path() == p/"d1" );
80 ++iter; // should recurse into d1
81 VERIFY( iter->path() == p/"d1/d2" );
82 iter.increment(ec); // should fail to recurse into p/d1/d2
83 VERIFY( ec );
84
85 // Test inaccessible sub-directory, skipping permission denied.
86 iter = fs::recursive_directory_iterator(p, opts, ec);
87 VERIFY( !ec );
88 VERIFY( iter != fs::recursive_directory_iterator() );
89 VERIFY( iter->path() == p/"d1" );
90 ++iter; // should recurse into d1
91 VERIFY( iter->path() == p/"d1/d2" );
92 iter.increment(ec); // should fail to recurse into p/d1/d2, so skip it
93 VERIFY( !ec );
94 VERIFY( iter == fs::recursive_directory_iterator() );
95
96 permissions(p/"d1/d2", fs::perms::owner_all, ec);
97 remove_all(p, ec);
98 }
99
100 void
101 test02()
102 {
103 std::error_code ec;
104 const auto p = __gnu_test::nonexistent_path();
105 create_directories(p / "d1/d2", ec);
106 VERIFY( !ec );
107
108 // Test post-increment (libstdc++/71005)
109 auto iter = fs::recursive_directory_iterator(p, ec);
110 VERIFY( !ec );
111 VERIFY( iter != fs::recursive_directory_iterator() );
112 const auto entry1 = *iter;
113 const auto entry2 = *iter++;
114 VERIFY( entry1 == entry2 );
115 VERIFY( entry1.path() == p/"d1" );
116 const auto entry3 = *iter;
117 const auto entry4 = *iter++;
118 VERIFY( entry3 == entry4 );
119 VERIFY( entry3.path() == p/"d1/d2" );
120 VERIFY( iter == fs::recursive_directory_iterator() );
121
122 remove_all(p, ec);
123 }
124
125 void
126 test03()
127 {
128 std::error_code ec;
129 const auto p = __gnu_test::nonexistent_path();
130 create_directories(p / "longer_than_small_string_buffer", ec);
131 VERIFY( !ec );
132
133 // Test for no reallocation on each dereference (this is a GNU extension)
134 auto iter = fs::recursive_directory_iterator(p, ec);
135 const auto* s1 = iter->path().c_str();
136 const auto* s2 = iter->path().c_str();
137 VERIFY( s1 == s2 );
138
139 remove_all(p, ec);
140 }
141
142 void
143 test04()
144 {
145 // libstdc++/71004
146 const fs::recursive_directory_iterator it;
147 VERIFY( it == fs::recursive_directory_iterator() );
148 }
149
150 void
151 test05()
152 {
153 auto p = __gnu_test::nonexistent_path();
154 create_directory(p);
155 create_directory_symlink(p, p / "l");
156 fs::recursive_directory_iterator it(p), endit;
157 VERIFY( begin(it) == it );
158 static_assert( noexcept(begin(it)), "begin is noexcept" );
159 VERIFY( end(it) == endit );
160 static_assert( noexcept(end(it)), "end is noexcept" );
161 }
162
163 int
164 main()
165 {
166 test01();
167 test02();
168 test03();
169 test04();
170 test05();
171 }