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 <fstream> 37 38 #include "atf-c++/macros.hpp" 39 40 #include "atf-c++/detail/exceptions.hpp" 41 #include "atf-c++/detail/fs.hpp" 42 43 #include "fs.hpp" 44 #include "user.hpp" 45 46 // ------------------------------------------------------------------------ 47 // Auxiliary functions. 48 // ------------------------------------------------------------------------ 49 50 static 51 void 52 create_file(const char *name) 53 { 54 std::ofstream os(name); 55 os.close(); 56 } 57 58 // ------------------------------------------------------------------------ 59 // Test cases for the "temp_dir" class. 60 // ------------------------------------------------------------------------ 61 62 ATF_TEST_CASE(temp_dir_raii); 63 ATF_TEST_CASE_HEAD(temp_dir_raii) 64 { 65 set_md_var("descr", "Tests the RAII behavior of the temp_dir class"); 66 } 67 ATF_TEST_CASE_BODY(temp_dir_raii) 68 { 69 using atf::atf_run::temp_dir; 70 71 atf::fs::path t1("non-existent"); 72 atf::fs::path t2("non-existent"); 73 74 { 75 atf::fs::path tmpl("testdir.XXXXXX"); 76 temp_dir td1(tmpl); 77 temp_dir td2(tmpl); 78 t1 = td1.get_path(); 79 t2 = td2.get_path(); 80 ATF_REQUIRE(t1.str().find("XXXXXX") == std::string::npos); 81 ATF_REQUIRE(t2.str().find("XXXXXX") == std::string::npos); 82 ATF_REQUIRE(t1 != t2); 83 ATF_REQUIRE(!atf::fs::exists(tmpl)); 84 ATF_REQUIRE( atf::fs::exists(t1)); 85 ATF_REQUIRE( atf::fs::exists(t2)); 86 87 atf::fs::file_info fi1(t1); 88 ATF_REQUIRE( fi1.is_owner_readable()); 89 ATF_REQUIRE( fi1.is_owner_writable()); 90 ATF_REQUIRE( fi1.is_owner_executable()); 91 ATF_REQUIRE(!fi1.is_group_readable()); 92 ATF_REQUIRE(!fi1.is_group_writable()); 93 ATF_REQUIRE(!fi1.is_group_executable()); 94 ATF_REQUIRE(!fi1.is_other_readable()); 95 ATF_REQUIRE(!fi1.is_other_writable()); 96 ATF_REQUIRE(!fi1.is_other_executable()); 97 98 atf::fs::file_info fi2(t2); 99 ATF_REQUIRE( fi2.is_owner_readable()); 100 ATF_REQUIRE( fi2.is_owner_writable()); 101 ATF_REQUIRE( fi2.is_owner_executable()); 102 ATF_REQUIRE(!fi2.is_group_readable()); 103 ATF_REQUIRE(!fi2.is_group_writable()); 104 ATF_REQUIRE(!fi2.is_group_executable()); 105 ATF_REQUIRE(!fi2.is_other_readable()); 106 ATF_REQUIRE(!fi2.is_other_writable()); 107 ATF_REQUIRE(!fi2.is_other_executable()); 108 } 109 110 ATF_REQUIRE(t1.str() != "non-existent"); 111 ATF_REQUIRE(!atf::fs::exists(t1)); 112 ATF_REQUIRE(t2.str() != "non-existent"); 113 ATF_REQUIRE(!atf::fs::exists(t2)); 114 } 115 116 117 // ------------------------------------------------------------------------ 118 // Test cases for the free functions. 119 // ------------------------------------------------------------------------ 120 121 ATF_TEST_CASE(cleanup); 122 ATF_TEST_CASE_HEAD(cleanup) 123 { 124 set_md_var("descr", "Tests the cleanup function"); 125 } 126 ATF_TEST_CASE_BODY(cleanup) 127 { 128 using atf::atf_run::cleanup; 129 130 ::mkdir("root", 0755); 131 ::mkdir("root/dir", 0755); 132 ::mkdir("root/dir/1", 0100); 133 ::mkdir("root/dir/2", 0644); 134 create_file("root/reg"); 135 136 atf::fs::path p("root"); 137 ATF_REQUIRE(atf::fs::exists(p)); 138 ATF_REQUIRE(atf::fs::exists(p / "dir")); 139 ATF_REQUIRE(atf::fs::exists(p / "dir/1")); 140 ATF_REQUIRE(atf::fs::exists(p / "dir/2")); 141 ATF_REQUIRE(atf::fs::exists(p / "reg")); 142 cleanup(p); 143 ATF_REQUIRE(!atf::fs::exists(p)); 144 } 145 146 ATF_TEST_CASE(cleanup_eacces_on_root); 147 ATF_TEST_CASE_HEAD(cleanup_eacces_on_root) 148 { 149 set_md_var("descr", "Tests the cleanup function"); 150 } 151 ATF_TEST_CASE_BODY(cleanup_eacces_on_root) 152 { 153 using atf::atf_run::cleanup; 154 155 ::mkdir("aux", 0755); 156 ::mkdir("aux/root", 0755); 157 ATF_REQUIRE(::chmod("aux", 0555) != -1); 158 159 try { 160 cleanup(atf::fs::path("aux/root")); 161 ATF_REQUIRE(atf::atf_run::is_root()); 162 } catch (const atf::system_error& e) { 163 ATF_REQUIRE(!atf::atf_run::is_root()); 164 ATF_REQUIRE_EQ(EACCES, e.code()); 165 } 166 } 167 168 ATF_TEST_CASE(cleanup_eacces_on_subdir); 169 ATF_TEST_CASE_HEAD(cleanup_eacces_on_subdir) 170 { 171 set_md_var("descr", "Tests the cleanup function"); 172 } 173 ATF_TEST_CASE_BODY(cleanup_eacces_on_subdir) 174 { 175 using atf::atf_run::cleanup; 176 177 ::mkdir("root", 0755); 178 ::mkdir("root/1", 0755); 179 ::mkdir("root/1/2", 0755); 180 ::mkdir("root/1/2/3", 0755); 181 ATF_REQUIRE(::chmod("root/1/2", 0555) != -1); 182 ATF_REQUIRE(::chmod("root/1", 0555) != -1); 183 184 const atf::fs::path p("root"); 185 cleanup(p); 186 ATF_REQUIRE(!atf::fs::exists(p)); 187 } 188 189 ATF_TEST_CASE(change_directory); 190 ATF_TEST_CASE_HEAD(change_directory) 191 { 192 set_md_var("descr", "Tests the change_directory function"); 193 } 194 ATF_TEST_CASE_BODY(change_directory) 195 { 196 using atf::atf_run::change_directory; 197 using atf::atf_run::get_current_dir; 198 199 ::mkdir("files", 0755); 200 ::mkdir("files/dir", 0755); 201 create_file("files/reg"); 202 203 const atf::fs::path old = get_current_dir(); 204 205 ATF_REQUIRE_THROW(atf::system_error, 206 change_directory(atf::fs::path("files/reg"))); 207 ATF_REQUIRE(get_current_dir() == old); 208 209 atf::fs::path old2 = change_directory(atf::fs::path("files")); 210 ATF_REQUIRE(old2 == old); 211 atf::fs::path old3 = change_directory(atf::fs::path("dir")); 212 ATF_REQUIRE(old3 == old2 / "files"); 213 atf::fs::path old4 = change_directory(atf::fs::path("../..")); 214 ATF_REQUIRE(old4 == old3 / "dir"); 215 ATF_REQUIRE(get_current_dir() == old); 216 } 217 218 ATF_TEST_CASE(get_current_dir); 219 ATF_TEST_CASE_HEAD(get_current_dir) 220 { 221 set_md_var("descr", "Tests the get_current_dir function"); 222 } 223 ATF_TEST_CASE_BODY(get_current_dir) 224 { 225 using atf::atf_run::change_directory; 226 using atf::atf_run::get_current_dir; 227 228 ::mkdir("files", 0755); 229 ::mkdir("files/dir", 0755); 230 create_file("files/reg"); 231 232 atf::fs::path curdir = get_current_dir(); 233 change_directory(atf::fs::path(".")); 234 ATF_REQUIRE(get_current_dir() == curdir); 235 change_directory(atf::fs::path("files")); 236 ATF_REQUIRE(get_current_dir() == curdir / "files"); 237 change_directory(atf::fs::path("dir")); 238 ATF_REQUIRE(get_current_dir() == curdir / "files/dir"); 239 change_directory(atf::fs::path("..")); 240 ATF_REQUIRE(get_current_dir() == curdir / "files"); 241 change_directory(atf::fs::path("..")); 242 ATF_REQUIRE(get_current_dir() == curdir); 243 } 244 245 // ------------------------------------------------------------------------ 246 // Main. 247 // ------------------------------------------------------------------------ 248 249 ATF_INIT_TEST_CASES(tcs) 250 { 251 // Add the tests for the "temp_dir" class. 252 ATF_ADD_TEST_CASE(tcs, temp_dir_raii); 253 254 // Add the tests for the free functions. 255 ATF_ADD_TEST_CASE(tcs, cleanup); 256 ATF_ADD_TEST_CASE(tcs, cleanup_eacces_on_root); 257 ATF_ADD_TEST_CASE(tcs, cleanup_eacces_on_subdir); 258 ATF_ADD_TEST_CASE(tcs, change_directory); 259 ATF_ADD_TEST_CASE(tcs, get_current_dir); 260 } 261