1// 2// Automated Testing Framework (atf) 3// 4// Copyright (c) 2007, 2008, 2009, 2010 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 30extern "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 50static 51void 52create_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 62ATF_TEST_CASE(temp_dir_raii); 63ATF_TEST_CASE_HEAD(temp_dir_raii) 64{ 65 set_md_var("descr", "Tests the RAII behavior of the temp_dir class"); 66} 67ATF_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 121ATF_TEST_CASE(cleanup); 122ATF_TEST_CASE_HEAD(cleanup) 123{ 124 set_md_var("descr", "Tests the cleanup function"); 125} 126ATF_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 146ATF_TEST_CASE(cleanup_eacces_on_root); 147ATF_TEST_CASE_HEAD(cleanup_eacces_on_root) 148{ 149 set_md_var("descr", "Tests the cleanup function"); 150} 151ATF_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 168ATF_TEST_CASE(cleanup_eacces_on_subdir); 169ATF_TEST_CASE_HEAD(cleanup_eacces_on_subdir) 170{ 171 set_md_var("descr", "Tests the cleanup function"); 172} 173ATF_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 189ATF_TEST_CASE(change_directory); 190ATF_TEST_CASE_HEAD(change_directory) 191{ 192 set_md_var("descr", "Tests the change_directory function"); 193} 194ATF_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 218ATF_TEST_CASE(get_current_dir); 219ATF_TEST_CASE_HEAD(get_current_dir) 220{ 221 set_md_var("descr", "Tests the get_current_dir function"); 222} 223ATF_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 249ATF_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