operations_unit_test.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. // operations_unit_test.cpp ----------------------------------------------------------//
  2. // Copyright Beman Dawes 2008, 2009, 2015
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // See http://www.boost.org/LICENSE_1_0.txt
  5. // Library home page: http://www.boost.org/libs/filesystem
  6. // ------------------------------------------------------------------------------------//
  7. // This program is misnamed - it is really a smoke test rather than a unit test
  8. // ------------------------------------------------------------------------------------//
  9. #include <boost/config/warning_disable.hpp>
  10. // See deprecated_test for tests of deprecated features
  11. #ifndef BOOST_FILESYSTEM_NO_DEPRECATED
  12. # define BOOST_FILESYSTEM_NO_DEPRECATED
  13. #endif
  14. #ifndef BOOST_SYSTEM_NO_DEPRECATED
  15. # define BOOST_SYSTEM_NO_DEPRECATED
  16. #endif
  17. #include <boost/filesystem.hpp> // make sure filesystem.hpp works
  18. #include <boost/config.hpp>
  19. # if defined( BOOST_NO_STD_WSTRING )
  20. # error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
  21. # endif
  22. #include <boost/system/error_code.hpp>
  23. #include <boost/detail/lightweight_test.hpp>
  24. #include <boost/detail/lightweight_main.hpp>
  25. #include <iostream>
  26. using namespace boost::filesystem;
  27. using namespace boost::system;
  28. using std::cout;
  29. using std::endl;
  30. using std::string;
  31. #define CHECK(x) check(x, __FILE__, __LINE__)
  32. namespace
  33. {
  34. bool cleanup = true;
  35. void check(bool ok, const char* file, int line)
  36. {
  37. if (ok) return;
  38. ++::boost::detail::test_errors();
  39. cout << file << '(' << line << "): test failed\n";
  40. }
  41. // file_status_test ----------------------------------------------------------------//
  42. void file_status_test()
  43. {
  44. cout << "file_status test..." << endl;
  45. file_status s = status(".");
  46. int v = s.permissions();
  47. cout << " status(\".\") permissions are "
  48. << std::oct << (v & 0777) << std::dec << endl;
  49. CHECK((v & 0400) == 0400);
  50. s = symlink_status(".");
  51. v = s.permissions();
  52. cout << " symlink_status(\".\") permissions are "
  53. << std::oct << (v & 0777) << std::dec << endl;
  54. CHECK((v & 0400) == 0400);
  55. }
  56. // query_test ----------------------------------------------------------------------//
  57. void query_test()
  58. {
  59. cout << "query test..." << endl;
  60. error_code ec;
  61. CHECK(file_size("no-such-file", ec) == static_cast<boost::uintmax_t>(-1));
  62. CHECK(ec == errc::no_such_file_or_directory);
  63. CHECK(status("no-such-file") == file_status(file_not_found, no_perms));
  64. CHECK(exists("/"));
  65. CHECK(is_directory("/"));
  66. CHECK(!exists("no-such-file"));
  67. exists("/", ec);
  68. if (ec)
  69. {
  70. cout << "exists(\"/\", ec) resulted in non-zero ec.value()" << endl;
  71. cout << "ec value: " << ec.value() << ", message: "<< ec.message() << endl;
  72. }
  73. CHECK(!ec);
  74. CHECK(exists("/"));
  75. CHECK(is_directory("/"));
  76. CHECK(!is_regular_file("/"));
  77. CHECK(!boost::filesystem::is_empty("/"));
  78. CHECK(!is_other("/"));
  79. }
  80. // directory_iterator_test -----------------------------------------------//
  81. void directory_iterator_test()
  82. {
  83. cout << "directory_iterator_test..." << endl;
  84. directory_iterator end;
  85. directory_iterator it(".");
  86. CHECK(!it->path().empty());
  87. if (is_regular_file(it->status()))
  88. {
  89. CHECK(is_regular_file(it->symlink_status()));
  90. CHECK(!is_directory(it->status()));
  91. CHECK(!is_symlink(it->status()));
  92. CHECK(!is_directory(it->symlink_status()));
  93. CHECK(!is_symlink(it->symlink_status()));
  94. }
  95. else
  96. {
  97. CHECK(is_directory(it->status()));
  98. CHECK(is_directory(it->symlink_status()));
  99. CHECK(!is_regular_file(it->status()));
  100. CHECK(!is_regular_file(it->symlink_status()));
  101. CHECK(!is_symlink(it->status()));
  102. CHECK(!is_symlink(it->symlink_status()));
  103. }
  104. for (; it != end; ++it)
  105. {
  106. //cout << " " << it->path() << "\n";
  107. }
  108. CHECK(directory_iterator(".") != directory_iterator());
  109. CHECK(directory_iterator() == end);
  110. #ifndef BOOST_NO_CXX11_RANGE_BASED_FOR
  111. for (directory_entry& x : directory_iterator("."))
  112. {
  113. CHECK(!x.path().empty());
  114. //cout << " " << x.path() << "\n";
  115. }
  116. const directory_iterator dir_itr(".");
  117. for (directory_entry& x : dir_itr)
  118. {
  119. CHECK(!x.path().empty());
  120. //cout << " " << x.path() << "\n";
  121. }
  122. #endif
  123. for (directory_iterator itr("."); itr != directory_iterator(); ++itr)
  124. {
  125. CHECK(!itr->path().empty());
  126. //cout << " " << itr->path() << "\n";
  127. }
  128. cout << "directory_iterator_test complete" << endl;
  129. }
  130. // recursive_directory_iterator_test -----------------------------------------------//
  131. void recursive_directory_iterator_test()
  132. {
  133. cout << "recursive_directory_iterator_test..." << endl;
  134. recursive_directory_iterator end;
  135. recursive_directory_iterator it(".");
  136. CHECK(!it->path().empty());
  137. if (is_regular_file(it->status()))
  138. {
  139. CHECK(is_regular_file(it->symlink_status()));
  140. CHECK(!is_directory(it->status()));
  141. CHECK(!is_symlink(it->status()));
  142. CHECK(!is_directory(it->symlink_status()));
  143. CHECK(!is_symlink(it->symlink_status()));
  144. }
  145. else
  146. {
  147. CHECK(is_directory(it->status()));
  148. CHECK(is_directory(it->symlink_status()));
  149. CHECK(!is_regular_file(it->status()));
  150. CHECK(!is_regular_file(it->symlink_status()));
  151. CHECK(!is_symlink(it->status()));
  152. CHECK(!is_symlink(it->symlink_status()));
  153. }
  154. for (; it != end; ++it)
  155. {
  156. //cout << " " << it->path() << "\n";
  157. }
  158. CHECK(recursive_directory_iterator(".") != recursive_directory_iterator());
  159. CHECK(recursive_directory_iterator() == end);
  160. #ifndef BOOST_NO_CXX11_RANGE_BASED_FOR
  161. for (directory_entry& x : recursive_directory_iterator("."))
  162. {
  163. CHECK(!x.path().empty());
  164. //cout << " " << x.path() << "\n";
  165. }
  166. const recursive_directory_iterator dir_itr(".");
  167. for (directory_entry& x : dir_itr)
  168. {
  169. CHECK(!x.path().empty());
  170. //cout << " " << x.path() << "\n";
  171. }
  172. #endif
  173. for (recursive_directory_iterator itr(".");
  174. itr != recursive_directory_iterator(); ++itr)
  175. {
  176. CHECK(!itr->path().empty());
  177. //cout << " " << itr->path() << "\n";
  178. }
  179. cout << "recursive_directory_iterator_test complete" << endl;
  180. }
  181. // operations_test -------------------------------------------------------//
  182. void operations_test()
  183. {
  184. cout << "operations test..." << endl;
  185. error_code ec;
  186. CHECK(!create_directory("/", ec));
  187. CHECK(!boost::filesystem::remove("no-such-file-or-directory"));
  188. CHECK(!remove_all("no-such-file-or-directory"));
  189. space_info info = space("/");
  190. CHECK(info.available <= info.capacity);
  191. CHECK(equivalent("/", "/"));
  192. CHECK(!equivalent("/", "."));
  193. std::time_t ft = last_write_time(".");
  194. ft = -1;
  195. last_write_time(".", ft, ec);
  196. }
  197. // directory_entry_test ------------------------------------------------------------//
  198. void directory_entry_test()
  199. {
  200. cout << "directory_entry test..." << endl;
  201. directory_entry de("foo.bar",
  202. file_status(regular_file, owner_all), file_status(directory_file, group_all));
  203. CHECK(de.path() == "foo.bar");
  204. CHECK(de.status() == file_status(regular_file, owner_all));
  205. CHECK(de.symlink_status() == file_status(directory_file, group_all));
  206. CHECK(de < directory_entry("goo.bar"));
  207. CHECK(de == directory_entry("foo.bar"));
  208. CHECK(de != directory_entry("goo.bar"));
  209. de.replace_filename("bar.foo");
  210. CHECK(de.path() == "bar.foo");
  211. }
  212. // directory_entry_overload_test ---------------------------------------------------//
  213. void directory_entry_overload_test()
  214. {
  215. cout << "directory_entry overload test..." << endl;
  216. directory_iterator it(".");
  217. path p(*it);
  218. }
  219. // error_handling_test -------------------------------------------------------------//
  220. void error_handling_test()
  221. {
  222. cout << "error handling test..." << endl;
  223. bool threw(false);
  224. try
  225. {
  226. file_size("no-such-file");
  227. }
  228. catch (const boost::filesystem::filesystem_error & ex)
  229. {
  230. threw = true;
  231. cout << "\nas expected, attempt to get size of non-existent file threw a filesystem_error\n"
  232. "what() returns " << ex.what() << "\n";
  233. }
  234. catch (...)
  235. {
  236. cout << "\nunexpected exception type caught" << endl;
  237. }
  238. CHECK(threw);
  239. error_code ec;
  240. CHECK(!create_directory("/", ec));
  241. }
  242. // string_file_tests ---------------------------------------------------------------//
  243. void string_file_tests(const path& temp_dir)
  244. {
  245. cout << "string_file_tests..." << endl;
  246. std::string contents("0123456789");
  247. path p(temp_dir / "string_file");
  248. save_string_file(p, contents);
  249. save_string_file(p, contents);
  250. BOOST_TEST_EQ(file_size(p), 10u);
  251. std::string round_trip;
  252. load_string_file(p, round_trip);
  253. BOOST_TEST_EQ(contents, round_trip);
  254. }
  255. } // unnamed namespace
  256. //--------------------------------------------------------------------------------------//
  257. // //
  258. // main //
  259. // //
  260. //--------------------------------------------------------------------------------------//
  261. int cpp_main(int argc, char* argv[])
  262. {
  263. // document state of critical macros
  264. #ifdef BOOST_POSIX_API
  265. cout << "BOOST_POSIX_API is defined\n";
  266. #endif
  267. #ifdef BOOST_WINDOWS_API
  268. cout << "BOOST_WINDOWS_API is defined\n";
  269. #endif
  270. cout << "BOOST_FILESYSTEM_DECL" << BOOST_STRINGIZE(=BOOST_FILESYSTEM_DECL) << "\n";
  271. cout << "BOOST_SYMBOL_VISIBLE" << BOOST_STRINGIZE(=BOOST_SYMBOL_VISIBLE) << "\n";
  272. cout << "current_path() is " << current_path().string() << endl;
  273. if (argc >= 2)
  274. {
  275. cout << "argv[1] is '" << argv[1] << "', changing current_path() to it" << endl;
  276. error_code ec;
  277. current_path( argv[1], ec );
  278. if (ec)
  279. {
  280. cout << "current_path('" << argv[1] << "') failed: " << ec << ": " << ec.message() << endl;
  281. }
  282. cout << "current_path() is " << current_path().string() << endl;
  283. }
  284. const path temp_dir(current_path() / ".." / unique_path("op-unit_test-%%%%-%%%%-%%%%"));
  285. cout << "temp_dir is " << temp_dir.string() << endl;
  286. create_directory(temp_dir);
  287. file_status_test();
  288. query_test();
  289. directory_iterator_test();
  290. recursive_directory_iterator_test();
  291. operations_test();
  292. directory_entry_test();
  293. directory_entry_overload_test();
  294. error_handling_test();
  295. string_file_tests(temp_dir);
  296. cout << unique_path() << endl;
  297. cout << unique_path("foo-%%%%%-%%%%%-bar") << endl;
  298. cout << unique_path("foo-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%-bar") << endl;
  299. cout << unique_path("foo-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-%%%%%-bar") << endl;
  300. cout << "testing complete" << endl;
  301. // post-test cleanup
  302. if (cleanup)
  303. {
  304. cout << "post-test removal of " << temp_dir << endl;
  305. BOOST_TEST(remove_all(temp_dir) != 0);
  306. // above was added just to simplify testing, but it ended up detecting
  307. // a bug (failure to close an internal search handle).
  308. cout << "post-test removal complete" << endl;
  309. // BOOST_TEST(!fs::exists(dir)); // nice test, but doesn't play well with TortoiseGit cache
  310. }
  311. return ::boost::report_errors();
  312. }