1 // operations_unit_test.cpp ----------------------------------------------------------//
3 // Copyright Beman Dawes 2008, 2009, 2015
5 // Distributed under the Boost Software License, Version 1.0.
6 // See http://www.boost.org/LICENSE_1_0.txt
8 // Library home page: http://www.boost.org/libs/filesystem
10 // ------------------------------------------------------------------------------------//
12 // This program is misnamed - it is really a smoke test rather than a unit test
14 // ------------------------------------------------------------------------------------//
17 #include <boost/config/warning_disable.hpp>
19 // See deprecated_test for tests of deprecated features
20 #ifndef BOOST_FILESYSTEM_NO_DEPRECATED
21 # define BOOST_FILESYSTEM_NO_DEPRECATED
23 #ifndef BOOST_SYSTEM_NO_DEPRECATED
24 # define BOOST_SYSTEM_NO_DEPRECATED
27 #include <boost/filesystem.hpp> // make sure filesystem.hpp works
29 #include <boost/config.hpp>
30 # if defined( BOOST_NO_STD_WSTRING )
31 # error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
34 #include <boost/system/error_code.hpp>
35 #include <boost/detail/lightweight_test.hpp>
36 #include <boost/detail/lightweight_main.hpp>
39 using namespace boost::filesystem
;
40 using namespace boost::system
;
45 #define CHECK(x) check(x, __FILE__, __LINE__)
51 void check(bool ok
, const char* file
, int line
)
55 ++::boost::detail::test_errors();
57 cout
<< file
<< '(' << line
<< "): test failed\n";
60 // file_status_test ----------------------------------------------------------------//
62 void file_status_test()
64 cout
<< "file_status test..." << endl
;
66 file_status s
= status(".");
67 int v
= s
.permissions();
68 cout
<< " status(\".\") permissions are "
69 << std::oct
<< (v
& 0777) << std::dec
<< endl
;
70 CHECK((v
& 0400) == 0400);
72 s
= symlink_status(".");
74 cout
<< " symlink_status(\".\") permissions are "
75 << std::oct
<< (v
& 0777) << std::dec
<< endl
;
76 CHECK((v
& 0400) == 0400);
79 // query_test ----------------------------------------------------------------------//
83 cout
<< "query test..." << endl
;
87 CHECK(file_size("no-such-file", ec
) == static_cast<boost::uintmax_t>(-1));
88 CHECK(ec
== errc::no_such_file_or_directory
);
90 CHECK(status("no-such-file") == file_status(file_not_found
, no_perms
));
93 CHECK(is_directory("/"));
94 CHECK(!exists("no-such-file"));
99 cout
<< "exists(\"/\", ec) resulted in non-zero ec.value()" << endl
;
100 cout
<< "ec value: " << ec
.value() << ", message: "<< ec
.message() << endl
;
105 CHECK(is_directory("/"));
106 CHECK(!is_regular_file("/"));
107 CHECK(!boost::filesystem::is_empty("/"));
108 CHECK(!is_other("/"));
111 // directory_iterator_test -----------------------------------------------//
113 void directory_iterator_test()
115 cout
<< "directory_iterator_test..." << endl
;
117 directory_iterator end
;
119 directory_iterator
it(".");
121 CHECK(!it
->path().empty());
123 if (is_regular_file(it
->status()))
125 CHECK(is_regular_file(it
->symlink_status()));
126 CHECK(!is_directory(it
->status()));
127 CHECK(!is_symlink(it
->status()));
128 CHECK(!is_directory(it
->symlink_status()));
129 CHECK(!is_symlink(it
->symlink_status()));
133 CHECK(is_directory(it
->status()));
134 CHECK(is_directory(it
->symlink_status()));
135 CHECK(!is_regular_file(it
->status()));
136 CHECK(!is_regular_file(it
->symlink_status()));
137 CHECK(!is_symlink(it
->status()));
138 CHECK(!is_symlink(it
->symlink_status()));
141 for (; it
!= end
; ++it
)
143 //cout << " " << it->path() << "\n";
146 CHECK(directory_iterator(".") != directory_iterator());
147 CHECK(directory_iterator() == end
);
149 #ifndef BOOST_NO_CXX11_RANGE_BASED_FOR
150 for (directory_entry
& x
: directory_iterator("."))
152 CHECK(!x
.path().empty());
153 //cout << " " << x.path() << "\n";
155 const directory_iterator
dir_itr(".");
156 for (directory_entry
& x
: dir_itr
)
158 CHECK(!x
.path().empty());
159 //cout << " " << x.path() << "\n";
163 for (directory_iterator
itr("."); itr
!= directory_iterator(); ++itr
)
165 CHECK(!itr
->path().empty());
166 //cout << " " << itr->path() << "\n";
169 cout
<< "directory_iterator_test complete" << endl
;
172 // recursive_directory_iterator_test -----------------------------------------------//
174 void recursive_directory_iterator_test()
176 cout
<< "recursive_directory_iterator_test..." << endl
;
178 recursive_directory_iterator end
;
180 recursive_directory_iterator
it(".");
182 CHECK(!it
->path().empty());
184 if (is_regular_file(it
->status()))
186 CHECK(is_regular_file(it
->symlink_status()));
187 CHECK(!is_directory(it
->status()));
188 CHECK(!is_symlink(it
->status()));
189 CHECK(!is_directory(it
->symlink_status()));
190 CHECK(!is_symlink(it
->symlink_status()));
194 CHECK(is_directory(it
->status()));
195 CHECK(is_directory(it
->symlink_status()));
196 CHECK(!is_regular_file(it
->status()));
197 CHECK(!is_regular_file(it
->symlink_status()));
198 CHECK(!is_symlink(it
->status()));
199 CHECK(!is_symlink(it
->symlink_status()));
202 for (; it
!= end
; ++it
)
204 //cout << " " << it->path() << "\n";
207 CHECK(recursive_directory_iterator("..") != recursive_directory_iterator());
208 CHECK(recursive_directory_iterator() == end
);
210 #ifndef BOOST_NO_CXX11_RANGE_BASED_FOR
211 for (directory_entry
& x
: recursive_directory_iterator(".."))
213 CHECK(!x
.path().empty());
214 //cout << " " << x.path() << "\n";
216 const recursive_directory_iterator
dir_itr("..");
217 for (directory_entry
& x
: dir_itr
)
219 CHECK(!x
.path().empty());
220 //cout << " " << x.path() << "\n";
224 for (recursive_directory_iterator
itr("..");
225 itr
!= recursive_directory_iterator(); ++itr
)
227 CHECK(!itr
->path().empty());
228 //cout << " " << itr->path() << "\n";
231 cout
<< "recursive_directory_iterator_test complete" << endl
;
234 // operations_test -------------------------------------------------------//
236 void operations_test()
238 cout
<< "operations test..." << endl
;
242 CHECK(!create_directory("/", ec
));
244 CHECK(!boost::filesystem::remove("no-such-file-or-directory"));
245 CHECK(!remove_all("no-such-file-or-directory"));
247 space_info info
= space("/");
249 CHECK(info
.available
<= info
.capacity
);
251 CHECK(equivalent("/", "/"));
252 CHECK(!equivalent("/", "."));
254 std::time_t ft
= last_write_time(".");
256 last_write_time(".", ft
, ec
);
259 // directory_entry_test ------------------------------------------------------------//
261 void directory_entry_test()
263 cout
<< "directory_entry test..." << endl
;
265 directory_entry
de("foo.bar",
266 file_status(regular_file
, owner_all
), file_status(directory_file
, group_all
));
268 CHECK(de
.path() == "foo.bar");
269 CHECK(de
.status() == file_status(regular_file
, owner_all
));
270 CHECK(de
.symlink_status() == file_status(directory_file
, group_all
));
271 CHECK(de
< directory_entry("goo.bar"));
272 CHECK(de
== directory_entry("foo.bar"));
273 CHECK(de
!= directory_entry("goo.bar"));
274 de
.replace_filename("bar.foo");
275 CHECK(de
.path() == "bar.foo");
278 // directory_entry_overload_test ---------------------------------------------------//
280 void directory_entry_overload_test()
282 cout
<< "directory_entry overload test..." << endl
;
284 directory_iterator
it(".");
288 // error_handling_test -------------------------------------------------------------//
290 void error_handling_test()
292 cout
<< "error handling test..." << endl
;
297 file_size("no-such-file");
299 catch (const boost::filesystem::filesystem_error
& ex
)
302 cout
<< "\nas expected, attempt to get size of non-existent file threw a filesystem_error\n"
303 "what() returns " << ex
.what() << "\n";
307 cout
<< "\nunexpected exception type caught" << endl
;
313 CHECK(!create_directory("/", ec
));
316 // string_file_tests ---------------------------------------------------------------//
318 void string_file_tests(const path
& temp_dir
)
320 cout
<< "string_file_tests..." << endl
;
321 std::string
contents("0123456789");
322 path
p(temp_dir
/ "string_file");
323 save_string_file(p
, contents
);
324 save_string_file(p
, contents
);
325 BOOST_TEST_EQ(file_size(p
), 10u);
326 std::string round_trip
;
327 load_string_file(p
, round_trip
);
328 BOOST_TEST_EQ(contents
, round_trip
);
331 } // unnamed namespace
333 //--------------------------------------------------------------------------------------//
337 //--------------------------------------------------------------------------------------//
339 int cpp_main(int argc
, char* argv
[])
341 // document state of critical macros
342 #ifdef BOOST_POSIX_API
343 cout
<< "BOOST_POSIX_API is defined\n";
345 #ifdef BOOST_WINDOWS_API
346 cout
<< "BOOST_WINDOWS_API is defined\n";
348 cout
<< "BOOST_FILESYSTEM_DECL" << BOOST_STRINGIZE(=BOOST_FILESYSTEM_DECL
) << "\n";
349 cout
<< "BOOST_SYMBOL_VISIBLE" << BOOST_STRINGIZE(=BOOST_SYMBOL_VISIBLE
) << "\n";
351 cout
<< "current_path() is " << current_path().string() << endl
;
355 cout
<< "argv[1] is '" << argv
[1] << "', changing current_path() to it" << endl
;
358 current_path( argv
[1], ec
);
362 cout
<< "current_path('" << argv
[1] << "') failed: " << ec
<< ": " << ec
.message() << endl
;
365 cout
<< "current_path() is " << current_path().string() << endl
;
368 const path
temp_dir(current_path() / ".." / unique_path("op-unit_test-%%%%-%%%%-%%%%"));
369 cout
<< "temp_dir is " << temp_dir
.string() << endl
;
371 create_directory(temp_dir
);
375 directory_iterator_test();
376 recursive_directory_iterator_test();
378 directory_entry_test();
379 directory_entry_overload_test();
380 error_handling_test();
381 string_file_tests(temp_dir
);
383 cout
<< unique_path() << endl
;
384 cout
<< unique_path("foo-%%%%%-%%%%%-bar") << endl
;
385 cout
<< unique_path("foo-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%-bar") << endl
;
386 cout
<< unique_path("foo-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-bar") << endl
;
388 cout
<< "testing complete" << endl
;
393 cout
<< "post-test removal of " << temp_dir
<< endl
;
394 BOOST_TEST(remove_all(temp_dir
) != 0);
395 // above was added just to simplify testing, but it ended up detecting
396 // a bug (failure to close an internal search handle).
397 cout
<< "post-test removal complete" << endl
;
398 // BOOST_TEST(!fs::exists(dir)); // nice test, but doesn't play well with TortoiseGit cache
401 return ::boost::report_errors();