Commit | Line | Data |
---|---|---|
0e23f538 TJ |
1 | /* |
2 | The software in this package is distributed under the GNU General | |
3 | Public License version 2 (with a special exception described below). | |
4 | ||
5 | A copy of GNU General Public License (GPL) is included in this distribution, | |
6 | in the file COPYING.GPL. | |
7 | ||
8 | As a special exception, if other files instantiate templates or use macros | |
9 | or inline functions from this file, or you compile this file and link it | |
10 | with other works to produce a work based on this file, this file | |
11 | does not by itself cause the resulting work to be covered | |
12 | by the GNU General Public License. | |
13 | ||
14 | However the source code for this file must still be made available | |
15 | in accordance with section (3) of the GNU General Public License. | |
16 | ||
17 | This exception does not invalidate any other reasons why a work based | |
18 | on this file might be covered by the GNU General Public License. | |
19 | */ | |
5de0c58a RP |
20 | /** @file |
21 | * | |
22 | * tests for the modules "filefunc", "daemonfunc" | |
23 | * | |
24 | * (c) Copyright 2007-2008 by Intra2net AG | |
5de0c58a RP |
25 | */ |
26 | ||
27 | //#define NOISEDEBUG | |
28 | ||
29 | #include <string> | |
30 | #include <vector> | |
31 | #include <list> | |
9fe0853b | 32 | #include <set> |
5de0c58a RP |
33 | #include <iostream> |
34 | #include <iomanip> | |
1a2fc4e8 | 35 | #include <fstream> |
5de0c58a RP |
36 | #include <sstream> |
37 | #include <algorithm> | |
38 | ||
9fe0853b TJ |
39 | #define BOOST_TEST_DYN_LINK |
40 | #include <boost/test/unit_test.hpp> | |
5de0c58a RP |
41 | |
42 | #include <filefunc.hxx> | |
90246b4a | 43 | #include <daemonfunc.hpp> |
34ed5e5e GE |
44 | #include <pipestream.hxx> |
45 | #include <stringfunc.hxx> | |
5de0c58a RP |
46 | |
47 | #ifdef NOISEDEBUG | |
48 | #define DOUT(msg) std::cout << msg << std::endl | |
49 | #else | |
50 | #define DOUT(msg) do {} while (0) | |
51 | #endif | |
52 | ||
1a2fc4e8 | 53 | using namespace std; |
5de0c58a RP |
54 | using namespace I2n; |
55 | ||
9fe0853b | 56 | class TestFileFuncFixture |
48d97d6c | 57 | { |
48d97d6c | 58 | protected: |
48d97d6c | 59 | typedef std::list< std::string > StringList; |
48d97d6c TJ |
60 | std::set<std::string> used_check_files; |
61 | ||
62 | std::string get_check_file_path(std::string tag) | |
63 | { | |
64 | std::string result; | |
65 | result= "__unittest__" + tag + ".dat"; | |
66 | used_check_files.insert(result); | |
67 | return result; | |
68 | } // eo get_check_file_path | |
69 | ||
48d97d6c TJ |
70 | void remove_check_files() |
71 | { | |
72 | for (std::set<std::string>::iterator it= used_check_files.begin(); | |
73 | it != used_check_files.end(); | |
74 | ++it) | |
75 | { | |
76 | std::string filepath(*it); | |
77 | if (path_exists(filepath)) | |
78 | { | |
79 | unlink(filepath); | |
80 | } | |
81 | //TODO | |
82 | } | |
83 | used_check_files.clear(); | |
84 | } // eo remove_check_files | |
85 | ||
48d97d6c | 86 | public: |
9fe0853b TJ |
87 | TestFileFuncFixture() |
88 | { | |
89 | } | |
48d97d6c | 90 | |
9fe0853b TJ |
91 | ~TestFileFuncFixture() |
92 | { | |
93 | remove_check_files(); | |
94 | } | |
95 | }; | |
48d97d6c | 96 | |
9fe0853b | 97 | BOOST_FIXTURE_TEST_SUITE(TestFileFunc, TestFileFuncFixture) |
48d97d6c | 98 | |
9fe0853b TJ |
99 | BOOST_AUTO_TEST_CASE(StatTest1) |
100 | { | |
c1a0882a | 101 | I2n::Stat stat(__FILE__); |
48d97d6c | 102 | |
9fe0853b TJ |
103 | BOOST_CHECK_EQUAL( true, (bool)stat ); |
104 | BOOST_CHECK_EQUAL( true, stat.is_regular_file() ); | |
105 | BOOST_CHECK_EQUAL( false, stat.is_directory() ); | |
48d97d6c | 106 | |
9fe0853b | 107 | stat= Stat("/dev/null"); |
48d97d6c | 108 | |
9fe0853b TJ |
109 | BOOST_CHECK_EQUAL( true, (bool)stat ); |
110 | BOOST_CHECK_EQUAL( false, stat.is_regular_file() ); | |
111 | BOOST_CHECK_EQUAL( false, stat.is_directory() ); | |
112 | BOOST_CHECK_EQUAL( true, stat.is_device() ); | |
113 | BOOST_CHECK_EQUAL( true, stat.is_character_device() ); | |
114 | BOOST_CHECK_EQUAL( false, stat.is_block_device() ); | |
115 | } // eo StatTest1 | |
48d97d6c | 116 | |
a9f2cccc GE |
117 | BOOST_AUTO_TEST_CASE(StatSize) |
118 | { | |
119 | write_file("/tmp/test","some nice content to make sure the file system optimizations don't inline this into the inode block"); | |
120 | ||
121 | I2n::Stat stat("/tmp/test"); | |
122 | ||
123 | BOOST_CHECK_EQUAL( true, (bool)stat ); | |
124 | BOOST_CHECK_EQUAL( true, stat.is_regular_file() ); | |
125 | ||
126 | BOOST_CHECK_EQUAL( true, ( stat.bytes_on_disk() >= 512 ) ); | |
127 | ||
128 | unlink("/tmp/test"); | |
129 | } // eo StatSize | |
130 | ||
96fe2dc5 GE |
131 | BOOST_AUTO_TEST_CASE(StatRecheck) |
132 | { | |
133 | // just to be sure | |
134 | unlink(".foobar"); | |
135 | ||
136 | I2n::Stat stat(".foobar"); | |
137 | BOOST_CHECK_EQUAL( false, (bool)stat ); | |
138 | ||
139 | write_file(".foobar","hello world"); | |
140 | ||
141 | stat.recheck(); | |
142 | ||
143 | BOOST_CHECK_EQUAL( true, (bool)stat ); | |
144 | BOOST_CHECK_EQUAL( true, stat.size() > 0 ); | |
145 | ||
146 | unlink(".foobar"); | |
147 | } | |
48d97d6c | 148 | |
9fe0853b TJ |
149 | BOOST_AUTO_TEST_CASE(DirTest1) |
150 | { | |
151 | typedef std::vector< std::string > StringVector; | |
152 | StringVector names; | |
48d97d6c | 153 | |
c1a0882a CH |
154 | string test_dir = dirname(__FILE__); |
155 | bool res= I2n::get_dir(test_dir,names); | |
48d97d6c | 156 | |
9fe0853b TJ |
157 | BOOST_CHECK_EQUAL( true, res ); |
158 | BOOST_CHECK( ! names.empty() ); | |
3f8a0632 | 159 | BOOST_CHECK_EQUAL(I2n::get_dir_count(test_dir), names.size()); |
48d97d6c | 160 | |
c1a0882a CH |
161 | BOOST_MESSAGE("Looking for " << basename(__FILE__) << " in " << test_dir); |
162 | StringVector::iterator it = std::find( names.begin(), names.end(), basename(__FILE__)); | |
9fe0853b | 163 | BOOST_CHECK( it != names.end() ); |
48d97d6c | 164 | |
9fe0853b TJ |
165 | it = std::find( names.begin(), names.end(), "." ); |
166 | BOOST_CHECK( it == names.end() ); | |
48d97d6c | 167 | |
c1a0882a | 168 | names= get_dir(test_dir,true); |
9fe0853b | 169 | BOOST_CHECK( ! names.empty() ); |
3f8a0632 | 170 | BOOST_CHECK_EQUAL(I2n::get_dir_count(test_dir, true), names.size()); |
48d97d6c | 171 | |
9fe0853b TJ |
172 | for (it= names.begin(); it!=names.end(); ++it) |
173 | { | |
174 | DOUT(" \"" << *it << "\""); | |
175 | BOOST_CHECK_EQUAL( false, it->empty() ); | |
176 | } | |
48d97d6c | 177 | |
9fe0853b TJ |
178 | it = std::find( names.begin(), names.end(), "." ); |
179 | BOOST_CHECK( it != names.end() ); | |
180 | } // eo DirTest1 | |
48d97d6c TJ |
181 | |
182 | ||
183 | ||
9fe0853b TJ |
184 | BOOST_AUTO_TEST_CASE(PathCuts1) |
185 | { | |
186 | std::string path1("/an/absolute/path"); | |
48d97d6c | 187 | |
9fe0853b TJ |
188 | BOOST_CHECK_EQUAL( std::string("/an/absolute"), dirname(path1) ); |
189 | BOOST_CHECK_EQUAL( std::string("path"), basename(path1) ); | |
48d97d6c | 190 | |
9fe0853b TJ |
191 | std::string path2("just.a.name"); |
192 | BOOST_CHECK_EQUAL( std::string("just.a.name"), basename(path2) ); | |
193 | BOOST_CHECK_EQUAL( std::string("."), dirname(path2) ); | |
194 | } // eo PathCuts1() | |
48d97d6c | 195 | |
48d97d6c | 196 | |
48d97d6c | 197 | |
9fe0853b TJ |
198 | BOOST_AUTO_TEST_CASE(NormalizePath1) |
199 | { | |
200 | std::string path; | |
48d97d6c | 201 | |
9fe0853b TJ |
202 | path= normalize_path("/a/simple/path/"); |
203 | BOOST_CHECK_EQUAL( std::string("/a/simple/path"), path ); | |
48d97d6c | 204 | |
9fe0853b TJ |
205 | path= normalize_path("//another///simple/.//path//"); |
206 | BOOST_CHECK_EQUAL( std::string("/another/simple/path"), path ); | |
19166500 | 207 | |
9fe0853b TJ |
208 | path= normalize_path("//..//..//a/dummy///../././simple/././/path//"); |
209 | BOOST_CHECK_EQUAL( std::string("/a/simple/path"), path ); | |
19166500 | 210 | |
9fe0853b TJ |
211 | path= normalize_path("../a/dummy//././..//simple//nice//absolute//.././..//relative/path//"); |
212 | BOOST_CHECK_EQUAL( std::string("../a/simple/relative/path"), path ); | |
19166500 | 213 | |
9fe0853b TJ |
214 | path= normalize_path("../../a/dummy//././..//simple/../nice//absolute//../.x/..//relative/path//"); |
215 | BOOST_CHECK_EQUAL( std::string("../../a/nice/relative/path"), path ); | |
19166500 | 216 | |
9fe0853b | 217 | } // eo NormalizePath1 |
19166500 | 218 | |
9fe0853b TJ |
219 | BOOST_AUTO_TEST_CASE(NormalizePath2) |
220 | { | |
221 | std::string path; | |
19166500 | 222 | |
9fe0853b TJ |
223 | path= normalize_path("/"); |
224 | BOOST_CHECK_EQUAL( std::string("/"), path ); | |
19166500 | 225 | |
9fe0853b TJ |
226 | path= normalize_path("//"); |
227 | BOOST_CHECK_EQUAL( std::string("/"), path ); | |
48d97d6c | 228 | |
9fe0853b TJ |
229 | path= normalize_path("/.//"); |
230 | BOOST_CHECK_EQUAL( std::string("/"), path ); | |
48d97d6c | 231 | |
9fe0853b TJ |
232 | path= normalize_path("."); |
233 | BOOST_CHECK_EQUAL( std::string(""), path ); | |
48d97d6c | 234 | |
9fe0853b TJ |
235 | path= normalize_path("./"); |
236 | BOOST_CHECK_EQUAL( std::string(""), path ); | |
48d97d6c | 237 | |
9fe0853b TJ |
238 | path= normalize_path(".///"); |
239 | BOOST_CHECK_EQUAL( std::string(""), path ); | |
48d97d6c | 240 | |
9fe0853b TJ |
241 | path= normalize_path("/./data/files"); |
242 | BOOST_CHECK_EQUAL( std::string("/data/files"), path ); | |
48d97d6c | 243 | |
9fe0853b TJ |
244 | path= normalize_path("./data/files/"); |
245 | BOOST_CHECK_EQUAL( std::string("data/files"), path ); | |
246 | } // eo NormalizePath2 | |
48d97d6c | 247 | |
9fe0853b TJ |
248 | BOOST_AUTO_TEST_CASE(TestUserAndGroupStuff1) |
249 | { | |
250 | User user_root((uid_t)0); | |
251 | BOOST_CHECK_EQUAL( true, user_root.is_valid() ); | |
252 | BOOST_CHECK_EQUAL( true, (bool)user_root ); | |
48d97d6c | 253 | |
9fe0853b TJ |
254 | BOOST_CHECK_EQUAL( std::string("root"), user_root.Name ); |
255 | BOOST_CHECK_EQUAL( (uid_t)0, user_root.Uid ); | |
256 | BOOST_CHECK_EQUAL( (gid_t)0, user_root.Gid ); | |
48d97d6c | 257 | |
9fe0853b TJ |
258 | User user_root2("root"); |
259 | BOOST_CHECK_EQUAL( true, user_root2.is_valid() ); | |
260 | BOOST_CHECK_EQUAL( true, (bool)user_root2 ); | |
48d97d6c | 261 | |
9fe0853b TJ |
262 | BOOST_CHECK_EQUAL( std::string("root"), user_root2.Name ); |
263 | BOOST_CHECK_EQUAL( (uid_t)0, user_root2.Uid ); | |
264 | BOOST_CHECK_EQUAL( (gid_t)0, user_root2.Gid ); | |
48d97d6c | 265 | |
9fe0853b TJ |
266 | Group group_root("root"); |
267 | BOOST_CHECK_EQUAL( true, group_root.is_valid() ); | |
268 | BOOST_CHECK_EQUAL( true, (bool)group_root ); | |
48d97d6c | 269 | |
9fe0853b TJ |
270 | BOOST_CHECK_EQUAL( std::string("root"), group_root.Name ); |
271 | BOOST_CHECK_EQUAL( (gid_t)0, group_root.Gid ); | |
48d97d6c | 272 | |
9fe0853b | 273 | } // TestUserAndGroupStuff1() |
48d97d6c | 274 | |
9fe0853b TJ |
275 | BOOST_AUTO_TEST_CASE(TestUserAndGroupStuff2) |
276 | { | |
277 | // Test if is_valid() works correctly | |
278 | User user_root; | |
279 | BOOST_CHECK_EQUAL( false, user_root.is_valid() ); | |
48d97d6c | 280 | |
9fe0853b TJ |
281 | Group group_root; |
282 | BOOST_CHECK_EQUAL( false, group_root.is_valid() ); | |
283 | } | |
48d97d6c | 284 | |
9fe0853b TJ |
285 | BOOST_AUTO_TEST_CASE(TestFileModes1) |
286 | { | |
287 | std::string path= get_check_file_path("FileModes1"); | |
48d97d6c | 288 | |
9fe0853b | 289 | write_file(path,"42"); |
48d97d6c | 290 | |
9fe0853b TJ |
291 | Stat stat(path, false); |
292 | BOOST_CHECK_EQUAL( true, stat.is_valid() ); | |
48d97d6c | 293 | |
9fe0853b TJ |
294 | User user( stat.uid() ); |
295 | Group group( stat.gid() ); | |
48d97d6c | 296 | |
9fe0853b TJ |
297 | BOOST_CHECK_EQUAL( true, user.is_valid() ); |
298 | BOOST_CHECK_EQUAL( true, group.is_valid() ); | |
48d97d6c | 299 | |
9fe0853b | 300 | bool res=chown( path, user.Name.c_str(), group.Gid ); |
48d97d6c | 301 | |
9fe0853b TJ |
302 | BOOST_CHECK_EQUAL( true, res ); |
303 | } // eo TestFileModes1() | |
48d97d6c | 304 | |
48d97d6c | 305 | |
48d97d6c | 306 | |
9fe0853b TJ |
307 | BOOST_AUTO_TEST_CASE(TestPidOf1) |
308 | { | |
309 | using I2n::Daemon::pid_of; | |
48d97d6c | 310 | |
9fe0853b | 311 | std::vector< pid_t > pid_list; |
1a2fc4e8 | 312 | |
9fe0853b | 313 | bool res= pid_of("init", pid_list); |
9fe0853b | 314 | BOOST_CHECK_EQUAL( true, res); |
246bcd58 GE |
315 | |
316 | if (pid_list.empty()) | |
317 | { | |
318 | res= pid_of("systemd", pid_list); | |
319 | BOOST_CHECK_EQUAL( true, res); | |
320 | } | |
321 | ||
9fe0853b | 322 | BOOST_CHECK_EQUAL( false, pid_list.empty() ); |
1a2fc4e8 | 323 | |
9fe0853b TJ |
324 | std::vector< pid_t >::const_iterator pos1 = |
325 | std::find( pid_list.begin(), pid_list.end(), 1); | |
48d97d6c | 326 | |
9fe0853b TJ |
327 | BOOST_CHECK( pos1 != pid_list.end() ); |
328 | } // eo TestPidOf1() | |
1a2fc4e8 | 329 | |
9fe0853b TJ |
330 | BOOST_AUTO_TEST_CASE(TestCopyFileSourceFail) |
331 | { | |
332 | bool res = copy_file("does not exist", "destination"); | |
333 | BOOST_CHECK_EQUAL( false, res ); | |
334 | } | |
48d97d6c | 335 | |
9fe0853b TJ |
336 | BOOST_AUTO_TEST_CASE(TestCopyFileDestFail) |
337 | { | |
338 | bool res = copy_file("/etc/HOSTNAME", "/proc/not/writable"); | |
339 | BOOST_CHECK_EQUAL( false, res ); | |
340 | } | |
5de0c58a | 341 | |
9fe0853b TJ |
342 | BOOST_AUTO_TEST_CASE(TestCopyFileOk) |
343 | { | |
344 | string input = "copy_source"; | |
345 | string data = "test"; | |
346 | ||
347 | long input_size = 0; | |
348 | ofstream finput(input.c_str()); | |
349 | if (finput) | |
350 | { | |
351 | finput << data; | |
352 | finput.close(); | |
353 | input_size = file_size(input); | |
354 | } | |
355 | ||
356 | string output = "copy_dest"; | |
357 | long output_size = 0; | |
358 | bool res = copy_file(input, output); | |
359 | if (res) | |
360 | { | |
361 | output_size = file_size(output); | |
362 | } | |
363 | unlink(input); | |
364 | unlink(output); | |
365 | ||
366 | bool size_is_zero = output_size == 0 ? true : false; | |
367 | ||
368 | BOOST_CHECK_EQUAL( true, res ); | |
369 | BOOST_CHECK_EQUAL( input_size, output_size ); | |
370 | BOOST_CHECK_EQUAL( false, size_is_zero ); | |
371 | } | |
372 | ||
faf8475b TJ |
373 | BOOST_AUTO_TEST_CASE(TestMkdtemp) |
374 | { | |
375 | // Create unique directory | |
376 | string unique_dir = I2n::mkdtemp("foobar.XXXXXX"); | |
377 | BOOST_REQUIRE(unique_dir.size() > 0); | |
378 | ||
379 | // Test if it's really a directory | |
380 | BOOST_CHECK_EQUAL(true, Stat(unique_dir).is_directory()); | |
381 | ||
382 | // Unlink it | |
997987a6 TJ |
383 | BOOST_CHECK_EQUAL(true, rmdir(unique_dir)); |
384 | } | |
385 | ||
386 | BOOST_AUTO_TEST_CASE(TestRecursiveDelete) | |
387 | { | |
388 | // Create unique directory | |
389 | string unique_dir = I2n::mkdtemp("foobar.XXXXXX"); | |
390 | BOOST_REQUIRE(unique_dir.size() > 0); | |
391 | ||
392 | // Test if it's really a directory | |
393 | BOOST_CHECK_EQUAL(true, Stat(unique_dir).is_directory()); | |
394 | ||
395 | // Create dirs and files below it | |
396 | const std::string sub_dir = unique_dir + "/" + "some_subdir"; | |
397 | const std::string some_file = sub_dir + "/" + "some_file"; | |
398 | BOOST_CHECK_EQUAL(true, I2n::mkdir(sub_dir)); | |
399 | BOOST_CHECK_EQUAL(true, write_file(some_file, "foobar")); | |
400 | ||
401 | // Unlink it | |
faf8475b | 402 | BOOST_CHECK_EQUAL(true, I2n::recursive_delete(unique_dir)); |
997987a6 TJ |
403 | BOOST_CHECK_EQUAL(false, Stat(unique_dir).is_directory()); |
404 | } | |
405 | ||
406 | BOOST_AUTO_TEST_CASE(TestRecursiveDeleteKeepParentDir) | |
407 | { | |
408 | // Create unique directory | |
409 | string unique_dir = I2n::mkdtemp("foobar.XXXXXX"); | |
410 | BOOST_REQUIRE(unique_dir.size() > 0); | |
411 | ||
412 | // Test if it's really a directory | |
413 | BOOST_CHECK_EQUAL(true, Stat(unique_dir).is_directory()); | |
414 | ||
415 | // Create dirs and files below it | |
416 | const std::string sub_dir = unique_dir + "/" + "some_subdir"; | |
417 | const std::string some_file = sub_dir + "/" + "some_file"; | |
418 | const std::string other_file = unique_dir + "/" + "other_file"; | |
419 | ||
420 | BOOST_CHECK_EQUAL(true, I2n::mkdir(sub_dir)); | |
421 | BOOST_CHECK_EQUAL(true, write_file(some_file, "foobar")); | |
422 | BOOST_CHECK_EQUAL(true, write_file(other_file, "foobar")); | |
423 | ||
424 | // Unlink it | |
425 | BOOST_CHECK_EQUAL(true, I2n::recursive_delete(unique_dir, true)); | |
426 | ||
427 | // check result | |
428 | BOOST_CHECK_EQUAL(true, Stat(unique_dir).is_directory()); | |
429 | BOOST_CHECK_EQUAL(false, Stat(sub_dir).is_directory()); | |
430 | BOOST_CHECK_EQUAL(false, Stat(other_file).is_regular_file()); | |
431 | ||
432 | BOOST_CHECK_EQUAL(true, I2n::rmdir(unique_dir)); | |
faf8475b TJ |
433 | } |
434 | ||
a50de522 GE |
435 | BOOST_AUTO_TEST_CASE(TestRecursiveDeleteSymlinkedDirs1) |
436 | { | |
437 | // Create unique directory | |
438 | string unique_dir = I2n::mkdtemp("foobar.XXXXXX"); | |
439 | BOOST_REQUIRE(unique_dir.size() > 0); | |
440 | ||
441 | // Test if it's really a directory | |
442 | BOOST_CHECK_EQUAL(true, Stat(unique_dir).is_directory()); | |
443 | ||
444 | // Create dirs and files below it | |
445 | const std::string sub_dir = unique_dir + "/" + "some_subdir"; | |
446 | const std::string some_file = sub_dir + "/" + "some_file"; | |
447 | const std::string dir_symlink_within_unique_dir = unique_dir + "/" + "dir_symlink_within_unique_dir"; | |
448 | BOOST_CHECK_EQUAL(true, I2n::mkdir(sub_dir)); | |
449 | BOOST_CHECK_EQUAL(true, write_file(some_file, "foobar")); | |
450 | BOOST_CHECK_EQUAL(true, symlink(sub_dir, dir_symlink_within_unique_dir)); | |
451 | ||
452 | // Unlink it | |
453 | BOOST_CHECK_EQUAL(true, I2n::recursive_delete(unique_dir)); | |
454 | BOOST_CHECK_EQUAL(false, Stat(unique_dir).is_directory()); | |
455 | } | |
456 | ||
457 | BOOST_AUTO_TEST_CASE(TestRecursiveDeleteSymlinkedDirs2) | |
458 | { | |
459 | // Create unique directory | |
460 | string unique_dir = I2n::mkdtemp("foobar.XXXXXX"); | |
461 | BOOST_REQUIRE(unique_dir.size() > 0); | |
462 | ||
463 | // Test if it's really a directory | |
464 | BOOST_CHECK_EQUAL(true, Stat(unique_dir).is_directory()); | |
465 | ||
466 | // Create another unique directory | |
467 | string other_unique_dir = I2n::mkdtemp("foobar_other.XXXXXX"); | |
468 | BOOST_REQUIRE(other_unique_dir.size() > 0); | |
469 | ||
470 | // Test if it's really a directory | |
471 | BOOST_CHECK_EQUAL(true, Stat(other_unique_dir).is_directory()); | |
472 | ||
473 | const std::string other_file = other_unique_dir + "/" + "other_file"; | |
474 | BOOST_CHECK_EQUAL(true, write_file(other_file, "foobar")); | |
475 | ||
476 | // Create dirs and files below it | |
477 | const std::string sub_dir = unique_dir + "/" + "some_subdir"; | |
478 | const std::string some_file = sub_dir + "/" + "some_file"; | |
479 | const std::string dir_symlink_to_outside_unique_dir = unique_dir + "/" + "dir_symlink_to_outside_unique_dir"; | |
480 | BOOST_CHECK_EQUAL(true, I2n::mkdir(sub_dir)); | |
481 | BOOST_CHECK_EQUAL(true, write_file(some_file, "foobar")); | |
482 | BOOST_CHECK_EQUAL(true, symlink(other_unique_dir, dir_symlink_to_outside_unique_dir)); | |
483 | ||
484 | // Unlink it | |
485 | BOOST_CHECK_EQUAL(true, I2n::recursive_delete(unique_dir)); | |
486 | BOOST_CHECK_EQUAL(false, Stat(unique_dir).is_directory()); | |
487 | ||
488 | // other unique dir must still be there | |
489 | BOOST_CHECK_EQUAL(true, Stat(other_unique_dir).is_directory()); | |
490 | BOOST_CHECK_EQUAL(true, Stat(other_file).is_regular_file()); | |
491 | ||
492 | // finally delete the other unique dir | |
493 | BOOST_CHECK_EQUAL(true, I2n::recursive_delete(other_unique_dir)); | |
494 | BOOST_CHECK_EQUAL(false, Stat(other_unique_dir).is_directory()); | |
495 | } | |
496 | ||
faf8475b TJ |
497 | BOOST_AUTO_TEST_CASE(TestMkdtempBrokenTemplate) |
498 | { | |
499 | // Broken directory template -> fail | |
500 | string unique_dir = I2n::mkdtemp("foobar.XXX"); | |
501 | BOOST_CHECK_EQUAL("", unique_dir); | |
502 | } | |
503 | ||
44725532 TJ |
504 | BOOST_AUTO_TEST_CASE(DirectoryCreation) |
505 | { | |
506 | string dirname = "test_directory"; | |
507 | ||
508 | I2n::rmdir (dirname); | |
509 | ||
510 | BOOST_CHECK_EQUAL(true, I2n::mkdir(dirname)); | |
511 | BOOST_CHECK_EQUAL(true, Stat(dirname).is_directory()); | |
512 | // Verify default permissions | |
513 | BOOST_CHECK_EQUAL(0700, Stat(dirname).mode()); | |
514 | ||
515 | BOOST_CHECK_EQUAL(true, I2n::rmdir(dirname)); | |
516 | ||
517 | // Second call must fail: Directory already deleted | |
518 | BOOST_CHECK_EQUAL(false, I2n::rmdir(dirname)); | |
519 | } | |
520 | ||
521 | BOOST_AUTO_TEST_CASE(DirectoryCreatePermission) | |
522 | { | |
523 | string dirname = "test_directory"; | |
524 | ||
901e2943 TJ |
525 | // Save and fix umask |
526 | mode_t previous_mask = I2n::umask(0); | |
44725532 TJ |
527 | |
528 | I2n::rmdir (dirname); | |
529 | BOOST_CHECK_EQUAL(true, I2n::mkdir(dirname, 0770)); | |
901e2943 | 530 | BOOST_CHECK_EQUAL(0770, Stat(dirname).mode()); |
44725532 TJ |
531 | I2n::rmdir (dirname); |
532 | ||
901e2943 TJ |
533 | // Restore umask |
534 | I2n::umask(previous_mask); | |
44725532 TJ |
535 | } |
536 | ||
537 | BOOST_AUTO_TEST_CASE(ChangeDirectory) | |
538 | { | |
539 | string current_directory = I2n::getcwd(); | |
540 | BOOST_REQUIRE(!current_directory.empty()); | |
541 | ||
542 | BOOST_CHECK_EQUAL(true, I2n::chdir("/")); | |
543 | BOOST_CHECK_EQUAL("/", I2n::getcwd()); | |
544 | ||
545 | BOOST_CHECK_EQUAL(true, I2n::chdir(current_directory)); | |
546 | BOOST_REQUIRE_EQUAL(current_directory, I2n::getcwd()); | |
547 | } | |
548 | ||
c5935370 TJ |
549 | BOOST_AUTO_TEST_CASE(WriteFileEmptyData) |
550 | { | |
551 | // just to be sure | |
552 | unlink(".foobar"); | |
553 | ||
554 | I2n::Stat stat(".foobar"); | |
555 | BOOST_CHECK_EQUAL( false, (bool)stat ); | |
556 | ||
557 | // Call write_file() with empty data. Should still create the file. | |
558 | write_file(".foobar",""); | |
559 | ||
560 | stat.recheck(); | |
561 | ||
562 | BOOST_CHECK_EQUAL( true, (bool)stat ); | |
563 | BOOST_CHECK_EQUAL( true, stat.size() == 0 ); | |
564 | ||
565 | unlink(".foobar"); | |
566 | } | |
567 | ||
9d1eb8c8 TJ |
568 | BOOST_AUTO_TEST_CASE(FileContentDiffersIsIdentical) |
569 | { | |
570 | BOOST_CHECK_EQUAL( false, file_content_differs("/etc/passwd", "/etc/passwd") ); | |
571 | } | |
572 | ||
573 | BOOST_AUTO_TEST_CASE(FileContentDiffersNonExistent) | |
574 | { | |
575 | BOOST_CHECK_EQUAL( true, file_content_differs("/etc/passwd", "abc") ); | |
576 | BOOST_CHECK_EQUAL( true, file_content_differs("abc", "/etc/passwd") ); | |
577 | } | |
578 | ||
579 | BOOST_AUTO_TEST_CASE(FileContentDiffersEqualSize) | |
580 | { | |
581 | const string name1 = "file1", name2 = "file2"; | |
582 | { | |
583 | ofstream out1(name1.c_str()); | |
584 | out1 << "abc"; | |
585 | ||
586 | ofstream out2(name2.c_str()); | |
587 | out2 << "xyz"; | |
588 | } | |
589 | ||
590 | bool res = file_content_differs(name1, name2); | |
591 | unlink(name1); | |
592 | unlink(name2); | |
593 | ||
594 | BOOST_CHECK_EQUAL( true, res ); | |
595 | } | |
596 | ||
34ed5e5e GE |
597 | BOOST_AUTO_TEST_CASE(FreeDiskSpace1) |
598 | { | |
b9dfab8b GE |
599 | long long dfout; |
600 | long long get_free_diskspace_tmp; | |
34ed5e5e | 601 | |
b9dfab8b GE |
602 | // we need a partition to do this test. we can't create our own because that would require root |
603 | // so we use /tmp and retry it a few times in case of an error | |
604 | int retries = 5; | |
605 | while (retries > 0) | |
606 | { | |
99e07fab | 607 | string dfstr=capture_exec("df -P -B 1 /tmp | tail -n 1 | sed \"s/ \\+/\\\\n/g\" | sed -n 4,4p"); |
b9dfab8b GE |
608 | |
609 | dfout=-1; | |
610 | string_to<long long>(dfstr,dfout); | |
611 | ||
612 | get_free_diskspace_tmp=get_free_diskspace("/tmp"); | |
613 | ||
614 | if ( dfout == get_free_diskspace_tmp ) | |
615 | break; | |
616 | ||
617 | retries--; | |
618 | } | |
34ed5e5e | 619 | |
b9dfab8b GE |
620 | // do the check again with BOOST_CHECK_EQUAL to show it in the unit test output |
621 | BOOST_CHECK_EQUAL( dfout, get_free_diskspace_tmp ); | |
34ed5e5e GE |
622 | } |
623 | ||
624 | BOOST_AUTO_TEST_CASE(FreeDiskSpace2) | |
625 | { | |
626 | BOOST_CHECK_EQUAL( -1, get_free_diskspace("/this/path/is/really/bogus") ); | |
627 | } | |
628 | ||
fcadd7ba GE |
629 | BOOST_AUTO_TEST_CASE(TestDu) |
630 | { | |
631 | // Create unique directory | |
632 | string unique_dir = I2n::mkdtemp("foobar.XXXXXX"); | |
633 | BOOST_REQUIRE(unique_dir.size() > 0); | |
634 | ||
635 | // Test if it's really a directory | |
636 | BOOST_CHECK_EQUAL(true, Stat(unique_dir).is_directory()); | |
637 | ||
638 | // Create dirs and files below it | |
639 | const std::string sub_dir = unique_dir + "/" + "some_subdir"; | |
640 | const std::string some_file = sub_dir + "/" + "some_file"; | |
641 | BOOST_CHECK_EQUAL(true, I2n::mkdir(sub_dir)); | |
642 | BOOST_CHECK_EQUAL(true, write_file(some_file, "foobar and some more data, even more that Tom would like to see in one line without linebreak but I still want to have it all here")); | |
643 | ||
f8f119bf | 644 | string dustr=capture_exec(string("du --block-size=1 --sum ")+unique_dir+" | cut -f 1"); |
05b4f5e8 GE |
645 | long long duout=-1; |
646 | string_to<long long>(dustr,duout); | |
fcadd7ba | 647 | |
74311678 GE |
648 | long long first_du=du(unique_dir); |
649 | ||
650 | BOOST_CHECK_EQUAL( duout, first_du ); | |
651 | ||
652 | // create hardlinks | |
653 | string cmd; | |
654 | cmd=string("ln ")+some_file+" hardlink1"; | |
655 | system(cmd.c_str()); | |
656 | ||
657 | cmd=string("ln ")+some_file+" hardlink2"; | |
658 | system(cmd.c_str()); | |
659 | ||
660 | cmd=string("ln ")+some_file+" hardlink3"; | |
661 | system(cmd.c_str()); | |
662 | ||
663 | long long du_with_hardlinks=du(unique_dir); | |
664 | ||
665 | BOOST_CHECK_EQUAL( first_du , du_with_hardlinks ); | |
fcadd7ba GE |
666 | |
667 | // Unlink it | |
668 | BOOST_CHECK_EQUAL(true, I2n::recursive_delete(unique_dir)); | |
669 | BOOST_CHECK_EQUAL(false, Stat(unique_dir).is_directory()); | |
99e07fab CH |
670 | |
671 | // remove links | |
672 | unlink("hardlink1"); | |
673 | unlink("hardlink2"); | |
674 | unlink("hardlink3"); | |
fcadd7ba GE |
675 | } |
676 | ||
677 | ||
678 | ||
9fe0853b | 679 | BOOST_AUTO_TEST_SUITE_END() |