• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  operations_unit_test.cpp  ----------------------------------------------------------//
2 
3 //  Copyright Beman Dawes 2008, 2009, 2015
4 
5 //  Distributed under the Boost Software License, Version 1.0.
6 //  See http://www.boost.org/LICENSE_1_0.txt
7 
8 //  Library home page: http://www.boost.org/libs/filesystem
9 
10 //  ------------------------------------------------------------------------------------//
11 
12 //  This program is misnamed - it is really a smoke test rather than a unit test
13 
14 //  ------------------------------------------------------------------------------------//
15 
16 
17 #include <boost/config/warning_disable.hpp>
18 
19 //  See deprecated_test for tests of deprecated features
20 #ifndef BOOST_FILESYSTEM_NO_DEPRECATED
21 #  define BOOST_FILESYSTEM_NO_DEPRECATED
22 #endif
23 #ifndef BOOST_SYSTEM_NO_DEPRECATED
24 #  define BOOST_SYSTEM_NO_DEPRECATED
25 #endif
26 
27 #include <boost/filesystem.hpp>   // make sure filesystem.hpp works
28 
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
32 # endif
33 
34 #include <boost/system/error_code.hpp>
35 #include <boost/core/lightweight_test.hpp>
36 #include <boost/detail/lightweight_main.hpp>
37 #include <iostream>
38 
39 using namespace boost::filesystem;
40 using namespace boost::system;
41 using std::cout;
42 using std::endl;
43 using std::string;
44 
45 #define CHECK(x) check(x, __FILE__, __LINE__)
46 
47 namespace
48 {
49   bool cleanup = true;
50 
check(bool ok,const char * file,int line)51   void check(bool ok, const char* file, int line)
52   {
53     if (ok) return;
54 
55     ++::boost::detail::test_errors();
56 
57     cout << file << '(' << line << "): test failed\n";
58   }
59 
60   //  file_status_test  ----------------------------------------------------------------//
61 
file_status_test()62   void file_status_test()
63   {
64     cout << "file_status test..." << endl;
65 
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);
71 
72     s = symlink_status(".");
73     v = s.permissions();
74     cout << "  symlink_status(\".\") permissions are "
75       << std::oct << (v & 0777) << std::dec << endl;
76     CHECK((v & 0400) == 0400);
77   }
78 
79   //  query_test  ----------------------------------------------------------------------//
80 
query_test()81   void query_test()
82   {
83     cout << "query test..." << endl;
84 
85     error_code ec;
86 
87     CHECK(file_size("no-such-file", ec) == static_cast<boost::uintmax_t>(-1));
88     CHECK(ec == errc::no_such_file_or_directory);
89 
90     CHECK(status("no-such-file") == file_status(file_not_found, no_perms));
91 
92     CHECK(exists("/"));
93     CHECK(is_directory("/"));
94     CHECK(!exists("no-such-file"));
95 
96     exists("/", ec);
97     if (ec)
98     {
99       cout << "exists(\"/\", ec) resulted in non-zero ec.value()" << endl;
100       cout << "ec value: " << ec.value() << ", message: "<< ec.message() << endl;
101     }
102     CHECK(!ec);
103 
104     CHECK(exists("/"));
105     CHECK(is_directory("/"));
106     CHECK(!is_regular_file("/"));
107     CHECK(!boost::filesystem::is_empty("/"));
108     CHECK(!is_other("/"));
109   }
110 
111   //  directory_iterator_test  -----------------------------------------------//
112 
directory_iterator_test()113   void directory_iterator_test()
114   {
115     cout << "directory_iterator_test..." << endl;
116 
117     directory_iterator end;
118 
119     directory_iterator it(".");
120 
121     CHECK(!it->path().empty());
122 
123     if (is_regular_file(it->status()))
124     {
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()));
130     }
131     else
132     {
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()));
139     }
140 
141     for (; it != end; ++it)
142     {
143       //cout << "  " << it->path() << "\n";
144     }
145 
146     CHECK(directory_iterator(".") != directory_iterator());
147     CHECK(directory_iterator() == end);
148 
149 #ifndef BOOST_NO_CXX11_RANGE_BASED_FOR
150     for (directory_entry& x : directory_iterator("."))
151     {
152       CHECK(!x.path().empty());
153        //cout << "  " << x.path() << "\n";
154     }
155     const directory_iterator dir_itr(".");
156     for (directory_entry& x : dir_itr)
157     {
158       CHECK(!x.path().empty());
159       //cout << "  " << x.path() << "\n";
160     }
161 #endif
162 
163     for (directory_iterator itr("."); itr != directory_iterator(); ++itr)
164     {
165       CHECK(!itr->path().empty());
166       //cout << "  " << itr->path() << "\n";
167     }
168 
169     cout << "directory_iterator_test complete" << endl;
170   }
171 
172   //  recursive_directory_iterator_test  -----------------------------------------------//
173 
recursive_directory_iterator_test()174   void recursive_directory_iterator_test()
175   {
176     cout << "recursive_directory_iterator_test..." << endl;
177 
178     recursive_directory_iterator end;
179 
180     recursive_directory_iterator it(".");
181 
182     CHECK(!it->path().empty());
183 
184     if (is_regular_file(it->status()))
185     {
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()));
191     }
192     else
193     {
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()));
200     }
201 
202     for (; it != end; ++it)
203     {
204       //cout << "  " << it->path() << "\n";
205     }
206 
207     CHECK(recursive_directory_iterator(".") != recursive_directory_iterator());
208     CHECK(recursive_directory_iterator() == end);
209 
210 #ifndef BOOST_NO_CXX11_RANGE_BASED_FOR
211     for (directory_entry& x : recursive_directory_iterator("."))
212     {
213       CHECK(!x.path().empty());
214       //cout << "  " << x.path() << "\n";
215     }
216     const recursive_directory_iterator dir_itr(".");
217     for (directory_entry& x : dir_itr)
218     {
219       CHECK(!x.path().empty());
220       //cout << "  " << x.path() << "\n";
221     }
222 #endif
223 
224     for (recursive_directory_iterator itr(".");
225       itr != recursive_directory_iterator(); ++itr)
226     {
227       CHECK(!itr->path().empty());
228       //cout << "  " << itr->path() << "\n";
229     }
230 
231     cout << "recursive_directory_iterator_test complete" << endl;
232   }
233 
234   //  operations_test  -------------------------------------------------------//
235 
operations_test()236   void operations_test()
237   {
238     cout << "operations test..." << endl;
239 
240     error_code ec;
241 
242     CHECK(!create_directory("/", ec));
243 
244     CHECK(!boost::filesystem::remove("no-such-file-or-directory"));
245     CHECK(!remove_all("no-such-file-or-directory"));
246 
247     space_info info = space("/");
248 
249     CHECK(info.available <= info.capacity);
250 
251     CHECK(equivalent("/", "/"));
252     CHECK(!equivalent("/", "."));
253 
254     std::time_t ft = last_write_time(".");
255     ft = -1;
256     last_write_time(".", ft, ec);
257   }
258 
259   //  directory_entry_test  ------------------------------------------------------------//
260 
directory_entry_test()261   void directory_entry_test()
262   {
263     cout << "directory_entry test..." << endl;
264 
265     directory_entry de("foo.bar",
266       file_status(regular_file, owner_all), file_status(directory_file, group_all));
267 
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");
276   }
277 
278   //  directory_entry_overload_test  ---------------------------------------------------//
279 
directory_entry_overload_test()280   void directory_entry_overload_test()
281   {
282     cout << "directory_entry overload test..." << endl;
283 
284     directory_iterator it(".");
285     path p(*it);
286   }
287 
288   //  error_handling_test  -------------------------------------------------------------//
289 
error_handling_test()290   void error_handling_test()
291   {
292     cout << "error handling test..." << endl;
293 
294     bool threw(false);
295     try
296     {
297       file_size("no-such-file");
298     }
299     catch (const boost::filesystem::filesystem_error & ex)
300     {
301       threw = true;
302       cout << "\nas expected, attempt to get size of non-existent file threw a filesystem_error\n"
303         "what() returns " << ex.what() << "\n";
304     }
305     catch (...)
306     {
307       cout << "\nunexpected exception type caught" << endl;
308     }
309 
310     CHECK(threw);
311 
312     error_code ec;
313     CHECK(!create_directory("/", ec));
314   }
315 
316   //  string_file_tests  ---------------------------------------------------------------//
317 
string_file_tests(const path & temp_dir)318   void string_file_tests(const path& temp_dir)
319   {
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);
329   }
330 
331 }  // unnamed namespace
332 
333 //--------------------------------------------------------------------------------------//
334 //                                                                                      //
335 //                                    main                                              //
336 //                                                                                      //
337 //--------------------------------------------------------------------------------------//
338 
cpp_main(int argc,char * argv[])339 int cpp_main(int argc, char* argv[])
340 {
341 // document state of critical macros
342 #ifdef BOOST_POSIX_API
343   cout << "BOOST_POSIX_API is defined\n";
344 #endif
345 #ifdef BOOST_WINDOWS_API
346   cout << "BOOST_WINDOWS_API is defined\n";
347 #endif
348   cout << "BOOST_FILESYSTEM_DECL" << BOOST_STRINGIZE(=BOOST_FILESYSTEM_DECL) << "\n";
349   cout << "BOOST_SYMBOL_VISIBLE" << BOOST_STRINGIZE(=BOOST_SYMBOL_VISIBLE) << "\n";
350 
351   cout << "current_path() is " << current_path().string() << endl;
352 
353   if (argc >= 2)
354   {
355     cout << "argv[1] is '" << argv[1] << "', changing current_path() to it" << endl;
356 
357     error_code ec;
358     current_path( argv[1], ec );
359 
360     if (ec)
361     {
362       cout << "current_path('" << argv[1] << "') failed: " << ec << ": " << ec.message() << endl;
363     }
364 
365     cout << "current_path() is " << current_path().string() << endl;
366   }
367 
368   const path temp_dir(current_path() / ".." / unique_path("op-unit_test-%%%%-%%%%-%%%%"));
369   cout << "temp_dir is " << temp_dir.string() << endl;
370 
371   create_directory(temp_dir);
372 
373   file_status_test();
374   query_test();
375   directory_iterator_test();
376   recursive_directory_iterator_test();
377   operations_test();
378   directory_entry_test();
379   directory_entry_overload_test();
380   error_handling_test();
381   string_file_tests(temp_dir);
382 
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;
387 
388   cout << "testing complete" << endl;
389 
390   // post-test cleanup
391   if (cleanup)
392   {
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
399   }
400 
401   return ::boost::report_errors();
402 }
403