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