Home | History | Annotate | Line # | Download | only in tools
fs_test.cpp revision 1.1.1.1.8.2
      1 //
      2 // Automated Testing Framework (atf)
      3 //
      4 // Copyright (c) 2007 The NetBSD Foundation, Inc.
      5 // All rights reserved.
      6 //
      7 // Redistribution and use in source and binary forms, with or without
      8 // modification, are permitted provided that the following conditions
      9 // are met:
     10 // 1. Redistributions of source code must retain the above copyright
     11 //    notice, this list of conditions and the following disclaimer.
     12 // 2. Redistributions in binary form must reproduce the above copyright
     13 //    notice, this list of conditions and the following disclaimer in the
     14 //    documentation and/or other materials provided with the distribution.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
     17 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
     18 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
     21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     23 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
     25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     26 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 //
     29 
     30 extern "C" {
     31 #include <sys/types.h>
     32 #include <sys/stat.h>
     33 }
     34 
     35 #include <cerrno>
     36 #include <cstdio>
     37 #include <fstream>
     38 
     39 #include <atf-c++.hpp>
     40 
     41 #include "exceptions.hpp"
     42 #include "fs.hpp"
     43 #include "user.hpp"
     44 
     45 // ------------------------------------------------------------------------
     46 // Auxiliary functions.
     47 // ------------------------------------------------------------------------
     48 
     49 static
     50 void
     51 create_file(const char *name)
     52 {
     53     std::ofstream os(name);
     54     os.close();
     55 }
     56 
     57 static
     58 void
     59 create_files(void)
     60 {
     61     ::mkdir("files", 0755);
     62     ::mkdir("files/dir", 0755);
     63 
     64     std::ofstream os("files/reg");
     65     os.close();
     66 
     67     // TODO: Should create all other file types (blk, chr, fifo, lnk, sock)
     68     // and test for them... but the underlying file system may not support
     69     // most of these.  Specially as we are working on /tmp, which can be
     70     // mounted with flags such as "nodev".  See how to deal with this
     71     // situation.
     72 }
     73 
     74 // ------------------------------------------------------------------------
     75 // Test cases for the "path" class.
     76 // ------------------------------------------------------------------------
     77 
     78 ATF_TEST_CASE(path_normalize);
     79 ATF_TEST_CASE_HEAD(path_normalize)
     80 {
     81     set_md_var("descr", "Tests the path's normalization");
     82 }
     83 ATF_TEST_CASE_BODY(path_normalize)
     84 {
     85     using tools::fs::path;
     86 
     87     ATF_REQUIRE_EQ(path(".").str(), ".");
     88     ATF_REQUIRE_EQ(path("..").str(), "..");
     89 
     90     ATF_REQUIRE_EQ(path("foo").str(), "foo");
     91     ATF_REQUIRE_EQ(path("foo/bar").str(), "foo/bar");
     92     ATF_REQUIRE_EQ(path("foo/bar/").str(), "foo/bar");
     93 
     94     ATF_REQUIRE_EQ(path("/foo").str(), "/foo");
     95     ATF_REQUIRE_EQ(path("/foo/bar").str(), "/foo/bar");
     96     ATF_REQUIRE_EQ(path("/foo/bar/").str(), "/foo/bar");
     97 
     98     ATF_REQUIRE_EQ(path("///foo").str(), "/foo");
     99     ATF_REQUIRE_EQ(path("///foo///bar").str(), "/foo/bar");
    100     ATF_REQUIRE_EQ(path("///foo///bar///").str(), "/foo/bar");
    101 }
    102 
    103 ATF_TEST_CASE(path_is_absolute);
    104 ATF_TEST_CASE_HEAD(path_is_absolute)
    105 {
    106     set_md_var("descr", "Tests the path::is_absolute function");
    107 }
    108 ATF_TEST_CASE_BODY(path_is_absolute)
    109 {
    110     using tools::fs::path;
    111 
    112     ATF_REQUIRE( path("/").is_absolute());
    113     ATF_REQUIRE( path("////").is_absolute());
    114     ATF_REQUIRE( path("////a").is_absolute());
    115     ATF_REQUIRE( path("//a//").is_absolute());
    116     ATF_REQUIRE(!path("a////").is_absolute());
    117     ATF_REQUIRE(!path("../foo").is_absolute());
    118 }
    119 
    120 ATF_TEST_CASE(path_is_root);
    121 ATF_TEST_CASE_HEAD(path_is_root)
    122 {
    123     set_md_var("descr", "Tests the path::is_root function");
    124 }
    125 ATF_TEST_CASE_BODY(path_is_root)
    126 {
    127     using tools::fs::path;
    128 
    129     ATF_REQUIRE( path("/").is_root());
    130     ATF_REQUIRE( path("////").is_root());
    131     ATF_REQUIRE(!path("////a").is_root());
    132     ATF_REQUIRE(!path("//a//").is_root());
    133     ATF_REQUIRE(!path("a////").is_root());
    134     ATF_REQUIRE(!path("../foo").is_root());
    135 }
    136 
    137 ATF_TEST_CASE(path_branch_path);
    138 ATF_TEST_CASE_HEAD(path_branch_path)
    139 {
    140     set_md_var("descr", "Tests the path::branch_path function");
    141 }
    142 ATF_TEST_CASE_BODY(path_branch_path)
    143 {
    144     using tools::fs::path;
    145 
    146     ATF_REQUIRE_EQ(path(".").branch_path().str(), ".");
    147     ATF_REQUIRE_EQ(path("foo").branch_path().str(), ".");
    148     ATF_REQUIRE_EQ(path("foo/bar").branch_path().str(), "foo");
    149     ATF_REQUIRE_EQ(path("/foo").branch_path().str(), "/");
    150     ATF_REQUIRE_EQ(path("/foo/bar").branch_path().str(), "/foo");
    151 }
    152 
    153 ATF_TEST_CASE(path_leaf_name);
    154 ATF_TEST_CASE_HEAD(path_leaf_name)
    155 {
    156     set_md_var("descr", "Tests the path::leaf_name function");
    157 }
    158 ATF_TEST_CASE_BODY(path_leaf_name)
    159 {
    160     using tools::fs::path;
    161 
    162     ATF_REQUIRE_EQ(path(".").leaf_name(), ".");
    163     ATF_REQUIRE_EQ(path("foo").leaf_name(), "foo");
    164     ATF_REQUIRE_EQ(path("foo/bar").leaf_name(), "bar");
    165     ATF_REQUIRE_EQ(path("/foo").leaf_name(), "foo");
    166     ATF_REQUIRE_EQ(path("/foo/bar").leaf_name(), "bar");
    167 }
    168 
    169 ATF_TEST_CASE(path_compare_equal);
    170 ATF_TEST_CASE_HEAD(path_compare_equal)
    171 {
    172     set_md_var("descr", "Tests the comparison for equality between paths");
    173 }
    174 ATF_TEST_CASE_BODY(path_compare_equal)
    175 {
    176     using tools::fs::path;
    177 
    178     ATF_REQUIRE(path("/") == path("///"));
    179     ATF_REQUIRE(path("/a") == path("///a"));
    180     ATF_REQUIRE(path("/a") == path("///a///"));
    181 
    182     ATF_REQUIRE(path("a/b/c") == path("a//b//c"));
    183     ATF_REQUIRE(path("a/b/c") == path("a//b//c///"));
    184 }
    185 
    186 ATF_TEST_CASE(path_compare_different);
    187 ATF_TEST_CASE_HEAD(path_compare_different)
    188 {
    189     set_md_var("descr", "Tests the comparison for difference between paths");
    190 }
    191 ATF_TEST_CASE_BODY(path_compare_different)
    192 {
    193     using tools::fs::path;
    194 
    195     ATF_REQUIRE(path("/") != path("//a/"));
    196     ATF_REQUIRE(path("/a") != path("a///"));
    197 
    198     ATF_REQUIRE(path("a/b/c") != path("a/b"));
    199     ATF_REQUIRE(path("a/b/c") != path("a//b"));
    200     ATF_REQUIRE(path("a/b/c") != path("/a/b/c"));
    201     ATF_REQUIRE(path("a/b/c") != path("/a//b//c"));
    202 }
    203 
    204 ATF_TEST_CASE(path_concat);
    205 ATF_TEST_CASE_HEAD(path_concat)
    206 {
    207     set_md_var("descr", "Tests the concatenation of multiple paths");
    208 }
    209 ATF_TEST_CASE_BODY(path_concat)
    210 {
    211     using tools::fs::path;
    212 
    213     ATF_REQUIRE_EQ((path("foo") / "bar").str(), "foo/bar");
    214     ATF_REQUIRE_EQ((path("foo/") / "/bar").str(), "foo/bar");
    215     ATF_REQUIRE_EQ((path("foo/") / "/bar/baz").str(), "foo/bar/baz");
    216     ATF_REQUIRE_EQ((path("foo/") / "///bar///baz").str(), "foo/bar/baz");
    217 }
    218 
    219 ATF_TEST_CASE(path_to_absolute);
    220 ATF_TEST_CASE_HEAD(path_to_absolute)
    221 {
    222     set_md_var("descr", "Tests the conversion of a relative path to an "
    223                "absolute one");
    224 }
    225 ATF_TEST_CASE_BODY(path_to_absolute)
    226 {
    227     using tools::fs::file_info;
    228     using tools::fs::path;
    229 
    230     create_files();
    231 
    232     {
    233         const path p(".");
    234         path pa = p.to_absolute();
    235         ATF_REQUIRE(pa.is_absolute());
    236 
    237         file_info fi(p);
    238         file_info fia(pa);
    239         ATF_REQUIRE_EQ(fi.get_device(), fia.get_device());
    240         ATF_REQUIRE_EQ(fi.get_inode(), fia.get_inode());
    241     }
    242 
    243     {
    244         const path p("files/reg");
    245         path pa = p.to_absolute();
    246         ATF_REQUIRE(pa.is_absolute());
    247 
    248         file_info fi(p);
    249         file_info fia(pa);
    250         ATF_REQUIRE_EQ(fi.get_device(), fia.get_device());
    251         ATF_REQUIRE_EQ(fi.get_inode(), fia.get_inode());
    252     }
    253 }
    254 
    255 ATF_TEST_CASE(path_op_less);
    256 ATF_TEST_CASE_HEAD(path_op_less)
    257 {
    258     set_md_var("descr", "Tests that the path's less-than operator works");
    259 }
    260 ATF_TEST_CASE_BODY(path_op_less)
    261 {
    262     using tools::fs::path;
    263 
    264     create_files();
    265 
    266     ATF_REQUIRE(!(path("aaa") < path("aaa")));
    267 
    268     ATF_REQUIRE(  path("aab") < path("abc"));
    269     ATF_REQUIRE(!(path("abc") < path("aab")));
    270 }
    271 
    272 // ------------------------------------------------------------------------
    273 // Test cases for the "directory" class.
    274 // ------------------------------------------------------------------------
    275 
    276 ATF_TEST_CASE(directory_read);
    277 ATF_TEST_CASE_HEAD(directory_read)
    278 {
    279     set_md_var("descr", "Tests the directory class creation, which reads "
    280                "the contents of a directory");
    281 }
    282 ATF_TEST_CASE_BODY(directory_read)
    283 {
    284     using tools::fs::directory;
    285     using tools::fs::path;
    286 
    287     create_files();
    288 
    289     directory d(path("files"));
    290     ATF_REQUIRE_EQ(d.size(), 4);
    291     ATF_REQUIRE(d.find(".") != d.end());
    292     ATF_REQUIRE(d.find("..") != d.end());
    293     ATF_REQUIRE(d.find("dir") != d.end());
    294     ATF_REQUIRE(d.find("reg") != d.end());
    295 }
    296 
    297 ATF_TEST_CASE(directory_file_info);
    298 ATF_TEST_CASE_HEAD(directory_file_info)
    299 {
    300     set_md_var("descr", "Tests that the file_info objects attached to the "
    301                "directory are valid");
    302 }
    303 ATF_TEST_CASE_BODY(directory_file_info)
    304 {
    305     using tools::fs::directory;
    306     using tools::fs::file_info;
    307     using tools::fs::path;
    308 
    309     create_files();
    310 
    311     directory d(path("files"));
    312 
    313     {
    314         directory::const_iterator iter = d.find("dir");
    315         ATF_REQUIRE(iter != d.end());
    316         const file_info& fi = (*iter).second;
    317         ATF_REQUIRE(fi.get_type() == file_info::dir_type);
    318     }
    319 
    320     {
    321         directory::const_iterator iter = d.find("reg");
    322         ATF_REQUIRE(iter != d.end());
    323         const file_info& fi = (*iter).second;
    324         ATF_REQUIRE(fi.get_type() == file_info::reg_type);
    325     }
    326 }
    327 
    328 ATF_TEST_CASE(directory_names);
    329 ATF_TEST_CASE_HEAD(directory_names)
    330 {
    331     set_md_var("descr", "Tests the directory's names method");
    332 }
    333 ATF_TEST_CASE_BODY(directory_names)
    334 {
    335     using tools::fs::directory;
    336     using tools::fs::path;
    337 
    338     create_files();
    339 
    340     directory d(path("files"));
    341     std::set< std::string > ns = d.names();
    342     ATF_REQUIRE_EQ(ns.size(), 4);
    343     ATF_REQUIRE(ns.find(".") != ns.end());
    344     ATF_REQUIRE(ns.find("..") != ns.end());
    345     ATF_REQUIRE(ns.find("dir") != ns.end());
    346     ATF_REQUIRE(ns.find("reg") != ns.end());
    347 }
    348 
    349 // ------------------------------------------------------------------------
    350 // Test cases for the "file_info" class.
    351 // ------------------------------------------------------------------------
    352 
    353 ATF_TEST_CASE(file_info_stat);
    354 ATF_TEST_CASE_HEAD(file_info_stat)
    355 {
    356     set_md_var("descr", "Tests the file_info creation and its basic contents");
    357 }
    358 ATF_TEST_CASE_BODY(file_info_stat)
    359 {
    360     using tools::fs::file_info;
    361     using tools::fs::path;
    362 
    363     create_files();
    364 
    365     {
    366         path p("files/dir");
    367         file_info fi(p);
    368         ATF_REQUIRE(fi.get_type() == file_info::dir_type);
    369     }
    370 
    371     {
    372         path p("files/reg");
    373         file_info fi(p);
    374         ATF_REQUIRE(fi.get_type() == file_info::reg_type);
    375     }
    376 }
    377 
    378 ATF_TEST_CASE(file_info_perms);
    379 ATF_TEST_CASE_HEAD(file_info_perms)
    380 {
    381     set_md_var("descr", "Tests the file_info methods to get the file's "
    382                "permissions");
    383 }
    384 ATF_TEST_CASE_BODY(file_info_perms)
    385 {
    386     using tools::fs::file_info;
    387     using tools::fs::path;
    388 
    389     path p("file");
    390 
    391     std::ofstream os(p.c_str());
    392     os.close();
    393 
    394 #define perms(ur, uw, ux, gr, gw, gx, othr, othw, othx) \
    395     { \
    396         file_info fi(p); \
    397         ATF_REQUIRE(fi.is_owner_readable() == ur); \
    398         ATF_REQUIRE(fi.is_owner_writable() == uw); \
    399         ATF_REQUIRE(fi.is_owner_executable() == ux); \
    400         ATF_REQUIRE(fi.is_group_readable() == gr); \
    401         ATF_REQUIRE(fi.is_group_writable() == gw); \
    402         ATF_REQUIRE(fi.is_group_executable() == gx); \
    403         ATF_REQUIRE(fi.is_other_readable() == othr); \
    404         ATF_REQUIRE(fi.is_other_writable() == othw); \
    405         ATF_REQUIRE(fi.is_other_executable() == othx); \
    406     }
    407 
    408     ::chmod(p.c_str(), 0000);
    409     perms(false, false, false, false, false, false, false, false, false);
    410 
    411     ::chmod(p.c_str(), 0001);
    412     perms(false, false, false, false, false, false, false, false, true);
    413 
    414     ::chmod(p.c_str(), 0010);
    415     perms(false, false, false, false, false, true, false, false, false);
    416 
    417     ::chmod(p.c_str(), 0100);
    418     perms(false, false, true, false, false, false, false, false, false);
    419 
    420     ::chmod(p.c_str(), 0002);
    421     perms(false, false, false, false, false, false, false, true, false);
    422 
    423     ::chmod(p.c_str(), 0020);
    424     perms(false, false, false, false, true, false, false, false, false);
    425 
    426     ::chmod(p.c_str(), 0200);
    427     perms(false, true, false, false, false, false, false, false, false);
    428 
    429     ::chmod(p.c_str(), 0004);
    430     perms(false, false, false, false, false, false, true, false, false);
    431 
    432     ::chmod(p.c_str(), 0040);
    433     perms(false, false, false, true, false, false, false, false, false);
    434 
    435     ::chmod(p.c_str(), 0400);
    436     perms(true, false, false, false, false, false, false, false, false);
    437 
    438     ::chmod(p.c_str(), 0644);
    439     perms(true, true, false, true, false, false, true, false, false);
    440 
    441     ::chmod(p.c_str(), 0755);
    442     perms(true, true, true, true, false, true, true, false, true);
    443 
    444     ::chmod(p.c_str(), 0777);
    445     perms(true, true, true, true, true, true, true, true, true);
    446 
    447 #undef perms
    448 }
    449 
    450 // ------------------------------------------------------------------------
    451 // Test cases for the "temp_dir" class.
    452 // ------------------------------------------------------------------------
    453 
    454 ATF_TEST_CASE(temp_dir_raii);
    455 ATF_TEST_CASE_HEAD(temp_dir_raii)
    456 {
    457     set_md_var("descr", "Tests the RAII behavior of the temp_dir class");
    458 }
    459 ATF_TEST_CASE_BODY(temp_dir_raii)
    460 {
    461     tools::fs::path t1("non-existent");
    462     tools::fs::path t2("non-existent");
    463 
    464     {
    465         tools::fs::path tmpl("testdir.XXXXXX");
    466         tools::fs::temp_dir td1(tmpl);
    467         tools::fs::temp_dir td2(tmpl);
    468         t1 = td1.get_path();
    469         t2 = td2.get_path();
    470         ATF_REQUIRE(t1.str().find("XXXXXX") == std::string::npos);
    471         ATF_REQUIRE(t2.str().find("XXXXXX") == std::string::npos);
    472         ATF_REQUIRE(t1 != t2);
    473         ATF_REQUIRE(!tools::fs::exists(tmpl));
    474         ATF_REQUIRE( tools::fs::exists(t1));
    475         ATF_REQUIRE( tools::fs::exists(t2));
    476 
    477         tools::fs::file_info fi1(t1);
    478         ATF_REQUIRE( fi1.is_owner_readable());
    479         ATF_REQUIRE( fi1.is_owner_writable());
    480         ATF_REQUIRE( fi1.is_owner_executable());
    481         ATF_REQUIRE(!fi1.is_group_readable());
    482         ATF_REQUIRE(!fi1.is_group_writable());
    483         ATF_REQUIRE(!fi1.is_group_executable());
    484         ATF_REQUIRE(!fi1.is_other_readable());
    485         ATF_REQUIRE(!fi1.is_other_writable());
    486         ATF_REQUIRE(!fi1.is_other_executable());
    487 
    488         tools::fs::file_info fi2(t2);
    489         ATF_REQUIRE( fi2.is_owner_readable());
    490         ATF_REQUIRE( fi2.is_owner_writable());
    491         ATF_REQUIRE( fi2.is_owner_executable());
    492         ATF_REQUIRE(!fi2.is_group_readable());
    493         ATF_REQUIRE(!fi2.is_group_writable());
    494         ATF_REQUIRE(!fi2.is_group_executable());
    495         ATF_REQUIRE(!fi2.is_other_readable());
    496         ATF_REQUIRE(!fi2.is_other_writable());
    497         ATF_REQUIRE(!fi2.is_other_executable());
    498     }
    499 
    500     ATF_REQUIRE(t1.str() != "non-existent");
    501     ATF_REQUIRE(!tools::fs::exists(t1));
    502     ATF_REQUIRE(t2.str() != "non-existent");
    503     ATF_REQUIRE(!tools::fs::exists(t2));
    504 }
    505 
    506 
    507 // ------------------------------------------------------------------------
    508 // Test cases for the free functions.
    509 // ------------------------------------------------------------------------
    510 
    511 ATF_TEST_CASE(exists);
    512 ATF_TEST_CASE_HEAD(exists)
    513 {
    514     set_md_var("descr", "Tests the exists function");
    515 }
    516 ATF_TEST_CASE_BODY(exists)
    517 {
    518     using tools::fs::exists;
    519     using tools::fs::path;
    520 
    521     create_files();
    522 
    523     ATF_REQUIRE( exists(path("files")));
    524     ATF_REQUIRE(!exists(path("file")));
    525     ATF_REQUIRE(!exists(path("files2")));
    526 
    527     ATF_REQUIRE( exists(path("files/.")));
    528     ATF_REQUIRE( exists(path("files/..")));
    529     ATF_REQUIRE( exists(path("files/dir")));
    530     ATF_REQUIRE( exists(path("files/reg")));
    531     ATF_REQUIRE(!exists(path("files/foo")));
    532 }
    533 
    534 ATF_TEST_CASE(is_executable);
    535 ATF_TEST_CASE_HEAD(is_executable)
    536 {
    537     set_md_var("descr", "Tests the is_executable function");
    538 }
    539 ATF_TEST_CASE_BODY(is_executable)
    540 {
    541     using tools::fs::is_executable;
    542     using tools::fs::path;
    543 
    544     create_files();
    545 
    546     ATF_REQUIRE( is_executable(path("files")));
    547     ATF_REQUIRE( is_executable(path("files/.")));
    548     ATF_REQUIRE( is_executable(path("files/..")));
    549     ATF_REQUIRE( is_executable(path("files/dir")));
    550 
    551     ATF_REQUIRE(!is_executable(path("non-existent")));
    552 
    553     ATF_REQUIRE(!is_executable(path("files/reg")));
    554     ATF_REQUIRE(::chmod("files/reg", 0755) != -1);
    555     ATF_REQUIRE( is_executable(path("files/reg")));
    556 }
    557 
    558 ATF_TEST_CASE(remove);
    559 ATF_TEST_CASE_HEAD(remove)
    560 {
    561     set_md_var("descr", "Tests the remove function");
    562 }
    563 ATF_TEST_CASE_BODY(remove)
    564 {
    565     using tools::fs::exists;
    566     using tools::fs::path;
    567     using tools::fs::remove;
    568 
    569     create_files();
    570 
    571     ATF_REQUIRE( exists(path("files/reg")));
    572     remove(path("files/reg"));
    573     ATF_REQUIRE(!exists(path("files/reg")));
    574 
    575     ATF_REQUIRE( exists(path("files/dir")));
    576     ATF_REQUIRE_THROW(tools::system_error, remove(path("files/dir")));
    577     ATF_REQUIRE( exists(path("files/dir")));
    578 }
    579 
    580 ATF_TEST_CASE(cleanup);
    581 ATF_TEST_CASE_HEAD(cleanup)
    582 {
    583     set_md_var("descr", "Tests the cleanup function");
    584 }
    585 ATF_TEST_CASE_BODY(cleanup)
    586 {
    587     using tools::fs::cleanup;
    588 
    589     ::mkdir("root", 0755);
    590     ::mkdir("root/dir", 0755);
    591     ::mkdir("root/dir/1", 0100);
    592     ::mkdir("root/dir/2", 0644);
    593     create_file("root/reg");
    594 
    595     tools::fs::path p("root");
    596     ATF_REQUIRE(tools::fs::exists(p));
    597     ATF_REQUIRE(tools::fs::exists(p / "dir"));
    598     ATF_REQUIRE(tools::fs::exists(p / "dir/1"));
    599     ATF_REQUIRE(tools::fs::exists(p / "dir/2"));
    600     ATF_REQUIRE(tools::fs::exists(p / "reg"));
    601     cleanup(p);
    602     ATF_REQUIRE(!tools::fs::exists(p));
    603 }
    604 
    605 ATF_TEST_CASE(cleanup_eacces_on_root);
    606 ATF_TEST_CASE_HEAD(cleanup_eacces_on_root)
    607 {
    608     set_md_var("descr", "Tests the cleanup function");
    609 }
    610 ATF_TEST_CASE_BODY(cleanup_eacces_on_root)
    611 {
    612     using tools::fs::cleanup;
    613 
    614     ::mkdir("aux", 0755);
    615     ::mkdir("aux/root", 0755);
    616     ATF_REQUIRE(::chmod("aux", 0555) != -1);
    617 
    618     try {
    619         cleanup(tools::fs::path("aux/root"));
    620         ATF_REQUIRE(tools::user::is_root());
    621     } catch (const tools::system_error& e) {
    622         ATF_REQUIRE(!tools::user::is_root());
    623         ATF_REQUIRE_EQ(EACCES, e.code());
    624     }
    625 }
    626 
    627 ATF_TEST_CASE(cleanup_eacces_on_subdir);
    628 ATF_TEST_CASE_HEAD(cleanup_eacces_on_subdir)
    629 {
    630     set_md_var("descr", "Tests the cleanup function");
    631 }
    632 ATF_TEST_CASE_BODY(cleanup_eacces_on_subdir)
    633 {
    634     using tools::fs::cleanup;
    635 
    636     ::mkdir("root", 0755);
    637     ::mkdir("root/1", 0755);
    638     ::mkdir("root/1/2", 0755);
    639     ::mkdir("root/1/2/3", 0755);
    640     ATF_REQUIRE(::chmod("root/1/2", 0555) != -1);
    641     ATF_REQUIRE(::chmod("root/1", 0555) != -1);
    642 
    643     const tools::fs::path p("root");
    644     cleanup(p);
    645     ATF_REQUIRE(!tools::fs::exists(p));
    646 }
    647 
    648 ATF_TEST_CASE(change_directory);
    649 ATF_TEST_CASE_HEAD(change_directory)
    650 {
    651     set_md_var("descr", "Tests the change_directory function");
    652 }
    653 ATF_TEST_CASE_BODY(change_directory)
    654 {
    655     using tools::fs::change_directory;
    656     using tools::fs::get_current_dir;
    657 
    658     ::mkdir("files", 0755);
    659     ::mkdir("files/dir", 0755);
    660     create_file("files/reg");
    661 
    662     const tools::fs::path old = get_current_dir();
    663 
    664     ATF_REQUIRE_THROW(tools::system_error,
    665                     change_directory(tools::fs::path("files/reg")));
    666     ATF_REQUIRE(get_current_dir() == old);
    667 
    668     tools::fs::path old2 = change_directory(tools::fs::path("files"));
    669     ATF_REQUIRE(old2 == old);
    670     tools::fs::path old3 = change_directory(tools::fs::path("dir"));
    671     ATF_REQUIRE(old3 == old2 / "files");
    672     tools::fs::path old4 = change_directory(tools::fs::path("../.."));
    673     ATF_REQUIRE(old4 == old3 / "dir");
    674     ATF_REQUIRE(get_current_dir() == old);
    675 }
    676 
    677 ATF_TEST_CASE(get_current_dir);
    678 ATF_TEST_CASE_HEAD(get_current_dir)
    679 {
    680     set_md_var("descr", "Tests the get_current_dir function");
    681 }
    682 ATF_TEST_CASE_BODY(get_current_dir)
    683 {
    684     using tools::fs::change_directory;
    685     using tools::fs::get_current_dir;
    686 
    687     ::mkdir("files", 0755);
    688     ::mkdir("files/dir", 0755);
    689     create_file("files/reg");
    690 
    691     tools::fs::path curdir = get_current_dir();
    692     change_directory(tools::fs::path("."));
    693     ATF_REQUIRE(get_current_dir() == curdir);
    694     change_directory(tools::fs::path("files"));
    695     ATF_REQUIRE(get_current_dir() == curdir / "files");
    696     change_directory(tools::fs::path("dir"));
    697     ATF_REQUIRE(get_current_dir() == curdir / "files/dir");
    698     change_directory(tools::fs::path(".."));
    699     ATF_REQUIRE(get_current_dir() == curdir / "files");
    700     change_directory(tools::fs::path(".."));
    701     ATF_REQUIRE(get_current_dir() == curdir);
    702 }
    703 
    704 // ------------------------------------------------------------------------
    705 // Main.
    706 // ------------------------------------------------------------------------
    707 
    708 ATF_INIT_TEST_CASES(tcs)
    709 {
    710     // Add the tests for the "path" class.
    711     ATF_ADD_TEST_CASE(tcs, path_normalize);
    712     ATF_ADD_TEST_CASE(tcs, path_is_absolute);
    713     ATF_ADD_TEST_CASE(tcs, path_is_root);
    714     ATF_ADD_TEST_CASE(tcs, path_branch_path);
    715     ATF_ADD_TEST_CASE(tcs, path_leaf_name);
    716     ATF_ADD_TEST_CASE(tcs, path_compare_equal);
    717     ATF_ADD_TEST_CASE(tcs, path_compare_different);
    718     ATF_ADD_TEST_CASE(tcs, path_concat);
    719     ATF_ADD_TEST_CASE(tcs, path_to_absolute);
    720     ATF_ADD_TEST_CASE(tcs, path_op_less);
    721 
    722     // Add the tests for the "file_info" class.
    723     ATF_ADD_TEST_CASE(tcs, file_info_stat);
    724     ATF_ADD_TEST_CASE(tcs, file_info_perms);
    725 
    726     // Add the tests for the "directory" class.
    727     ATF_ADD_TEST_CASE(tcs, directory_read);
    728     ATF_ADD_TEST_CASE(tcs, directory_names);
    729     ATF_ADD_TEST_CASE(tcs, directory_file_info);
    730 
    731     // Add the tests for the "temp_dir" class.
    732     ATF_ADD_TEST_CASE(tcs, temp_dir_raii);
    733 
    734     // Add the tests for the free functions.
    735     ATF_ADD_TEST_CASE(tcs, exists);
    736     ATF_ADD_TEST_CASE(tcs, is_executable);
    737     ATF_ADD_TEST_CASE(tcs, remove);
    738     ATF_ADD_TEST_CASE(tcs, cleanup);
    739     ATF_ADD_TEST_CASE(tcs, cleanup_eacces_on_root);
    740     ATF_ADD_TEST_CASE(tcs, cleanup_eacces_on_subdir);
    741     ATF_ADD_TEST_CASE(tcs, change_directory);
    742     ATF_ADD_TEST_CASE(tcs, get_current_dir);
    743 }
    744