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/stat.h> 32 33 #include <signal.h> 34 #include <unistd.h> 35 } 36 37 #include <cstdlib> 38 #include <fstream> 39 #include <iomanip> 40 #include <ios> 41 #include <iostream> 42 #include <string> 43 44 #include "atf-c++/macros.hpp" 45 46 #include "atf-c++/detail/env.hpp" 47 #include "atf-c++/detail/fs.hpp" 48 #include "atf-c++/detail/process.hpp" 49 #include "atf-c++/detail/sanity.hpp" 50 51 // ------------------------------------------------------------------------ 52 // Auxiliary functions. 53 // ------------------------------------------------------------------------ 54 55 static 56 void 57 touch(const std::string& path) 58 { 59 std::ofstream os(path.c_str()); 60 if (!os) 61 ATF_FAIL("Could not create file " + path); 62 os.close(); 63 } 64 65 // ------------------------------------------------------------------------ 66 // Helper tests for "t_integration". 67 // ------------------------------------------------------------------------ 68 69 ATF_TEST_CASE(pass); 70 ATF_TEST_CASE_HEAD(pass) 71 { 72 set_md_var("descr", "Helper test case for the t_integration test program"); 73 } 74 ATF_TEST_CASE_BODY(pass) 75 { 76 } 77 78 ATF_TEST_CASE(config); 79 ATF_TEST_CASE_HEAD(config) 80 { 81 set_md_var("descr", "Helper test case for the t_integration test program"); 82 } 83 ATF_TEST_CASE_BODY(config) 84 { 85 std::cout << "1st: " << get_config_var("1st") << "\n"; 86 std::cout << "2nd: " << get_config_var("2nd") << "\n"; 87 std::cout << "3rd: " << get_config_var("3rd") << "\n"; 88 std::cout << "4th: " << get_config_var("4th") << "\n"; 89 } 90 91 ATF_TEST_CASE(fds); 92 ATF_TEST_CASE_HEAD(fds) 93 { 94 set_md_var("descr", "Helper test case for the t_integration test program"); 95 } 96 ATF_TEST_CASE_BODY(fds) 97 { 98 std::cout << "msg1 to stdout" << "\n"; 99 std::cout << "msg2 to stdout" << "\n"; 100 std::cerr << "msg1 to stderr" << "\n"; 101 std::cerr << "msg2 to stderr" << "\n"; 102 } 103 104 ATF_TEST_CASE_WITHOUT_HEAD(mux_streams); 105 ATF_TEST_CASE_BODY(mux_streams) 106 { 107 for (size_t i = 0; i < 10000; i++) { 108 switch (i % 5) { 109 case 0: 110 std::cout << "stdout " << i << "\n"; 111 break; 112 case 1: 113 std::cerr << "stderr " << i << "\n"; 114 break; 115 case 2: 116 std::cout << "stdout " << i << "\n"; 117 std::cerr << "stderr " << i << "\n"; 118 break; 119 case 3: 120 std::cout << "stdout " << i << "\n"; 121 std::cout << "stdout " << i << "\n"; 122 std::cerr << "stderr " << i << "\n"; 123 break; 124 case 4: 125 std::cout << "stdout " << i << "\n"; 126 std::cerr << "stderr " << i << "\n"; 127 std::cerr << "stderr " << i << "\n"; 128 break; 129 default: 130 UNREACHABLE; 131 } 132 } 133 } 134 135 ATF_TEST_CASE(testvar); 136 ATF_TEST_CASE_HEAD(testvar) 137 { 138 set_md_var("descr", "Helper test case for the t_integration test program"); 139 } 140 ATF_TEST_CASE_BODY(testvar) 141 { 142 if (!has_config_var("testvar")) 143 fail("testvar variable not defined"); 144 std::cout << "testvar: " << get_config_var("testvar") << "\n"; 145 } 146 147 ATF_TEST_CASE(env_list); 148 ATF_TEST_CASE_HEAD(env_list) 149 { 150 set_md_var("descr", "Helper test case for the t_integration test program"); 151 } 152 ATF_TEST_CASE_BODY(env_list) 153 { 154 const atf::process::status s = 155 atf::process::exec(atf::fs::path("env"), 156 atf::process::argv_array("env", NULL), 157 atf::process::stream_inherit(), 158 atf::process::stream_inherit()); 159 ATF_REQUIRE(s.exited()); 160 ATF_REQUIRE(s.exitstatus() == EXIT_SUCCESS); 161 } 162 163 ATF_TEST_CASE(env_home); 164 ATF_TEST_CASE_HEAD(env_home) 165 { 166 set_md_var("descr", "Helper test case for the t_integration test program"); 167 } 168 ATF_TEST_CASE_BODY(env_home) 169 { 170 ATF_REQUIRE(atf::env::has("HOME")); 171 atf::fs::path p(atf::env::get("HOME")); 172 atf::fs::file_info fi1(p); 173 atf::fs::file_info fi2(atf::fs::path(".")); 174 ATF_REQUIRE_EQ(fi1.get_device(), fi2.get_device()); 175 ATF_REQUIRE_EQ(fi1.get_inode(), fi2.get_inode()); 176 } 177 178 ATF_TEST_CASE(read_stdin); 179 ATF_TEST_CASE_HEAD(read_stdin) 180 { 181 set_md_var("descr", "Helper test case for the t_integration test program"); 182 } 183 ATF_TEST_CASE_BODY(read_stdin) 184 { 185 char buf[100]; 186 ssize_t len = ::read(STDIN_FILENO, buf, sizeof(buf) - 1); 187 ATF_REQUIRE(len != -1); 188 189 buf[len + 1] = '\0'; 190 for (ssize_t i = 0; i < len; i++) { 191 if (buf[i] != '\0') { 192 fail("The stdin of the test case does not seem to be /dev/zero; " 193 "got '" + std::string(buf) + "'"); 194 } 195 } 196 } 197 198 ATF_TEST_CASE(umask); 199 ATF_TEST_CASE_HEAD(umask) 200 { 201 set_md_var("descr", "Helper test case for the t_integration test program"); 202 } 203 ATF_TEST_CASE_BODY(umask) 204 { 205 mode_t m = ::umask(0); 206 std::cout << "umask: " << std::setw(4) << std::setfill('0') 207 << std::oct << m << "\n"; 208 (void)::umask(m); 209 } 210 211 ATF_TEST_CASE_WITH_CLEANUP(cleanup_states); 212 ATF_TEST_CASE_HEAD(cleanup_states) 213 { 214 set_md_var("descr", "Helper test case for the t_integration test program"); 215 } 216 ATF_TEST_CASE_BODY(cleanup_states) 217 { 218 touch(get_config_var("statedir") + "/to-delete"); 219 touch(get_config_var("statedir") + "/to-stay"); 220 221 if (get_config_var("state") == "fail") 222 ATF_FAIL("On purpose"); 223 else if (get_config_var("state") == "skip") 224 ATF_SKIP("On purpose"); 225 } 226 ATF_TEST_CASE_CLEANUP(cleanup_states) 227 { 228 atf::fs::remove(atf::fs::path(get_config_var("statedir") + "/to-delete")); 229 } 230 231 ATF_TEST_CASE_WITH_CLEANUP(cleanup_curdir); 232 ATF_TEST_CASE_HEAD(cleanup_curdir) 233 { 234 set_md_var("descr", "Helper test case for the t_integration test program"); 235 } 236 ATF_TEST_CASE_BODY(cleanup_curdir) 237 { 238 std::ofstream os("oldvalue"); 239 if (!os) 240 ATF_FAIL("Failed to create oldvalue file"); 241 os << 1234; 242 os.close(); 243 } 244 ATF_TEST_CASE_CLEANUP(cleanup_curdir) 245 { 246 std::ifstream is("oldvalue"); 247 if (is) { 248 int i; 249 is >> i; 250 std::cout << "Old value: " << i << "\n"; 251 is.close(); 252 } 253 } 254 255 ATF_TEST_CASE(require_arch); 256 ATF_TEST_CASE_HEAD(require_arch) 257 { 258 set_md_var("descr", "Helper test case for the t_integration test program"); 259 set_md_var("require.arch", get_config_var("arch", "not-set")); 260 } 261 ATF_TEST_CASE_BODY(require_arch) 262 { 263 } 264 265 ATF_TEST_CASE(require_config); 266 ATF_TEST_CASE_HEAD(require_config) 267 { 268 set_md_var("descr", "Helper test case for the t_integration test program"); 269 set_md_var("require.config", "var1 var2"); 270 } 271 ATF_TEST_CASE_BODY(require_config) 272 { 273 std::cout << "var1: " << get_config_var("var1") << "\n"; 274 std::cout << "var2: " << get_config_var("var2") << "\n"; 275 } 276 277 ATF_TEST_CASE(require_files); 278 ATF_TEST_CASE_HEAD(require_files) 279 { 280 set_md_var("descr", "Helper test case for the t_integration test program"); 281 set_md_var("require.files", get_config_var("files", "not-set")); 282 } 283 ATF_TEST_CASE_BODY(require_files) 284 { 285 } 286 287 ATF_TEST_CASE(require_machine); 288 ATF_TEST_CASE_HEAD(require_machine) 289 { 290 set_md_var("descr", "Helper test case for the t_integration test program"); 291 set_md_var("require.machine", get_config_var("machine", "not-set")); 292 } 293 ATF_TEST_CASE_BODY(require_machine) 294 { 295 } 296 297 ATF_TEST_CASE(require_progs); 298 ATF_TEST_CASE_HEAD(require_progs) 299 { 300 set_md_var("descr", "Helper test case for the t_integration test program"); 301 set_md_var("require.progs", get_config_var("progs", "not-set")); 302 } 303 ATF_TEST_CASE_BODY(require_progs) 304 { 305 } 306 307 ATF_TEST_CASE(require_user); 308 ATF_TEST_CASE_HEAD(require_user) 309 { 310 set_md_var("descr", "Helper test case for the t_integration test program"); 311 set_md_var("require.user", get_config_var("user", "not-set")); 312 } 313 ATF_TEST_CASE_BODY(require_user) 314 { 315 } 316 317 ATF_TEST_CASE(timeout); 318 ATF_TEST_CASE_HEAD(timeout) 319 { 320 set_md_var("descr", "Helper test case for the t_integration test program"); 321 set_md_var("timeout", "1"); 322 } 323 ATF_TEST_CASE_BODY(timeout) 324 { 325 sleep(10); 326 touch(get_config_var("statedir") + "/finished"); 327 } 328 329 ATF_TEST_CASE(timeout_forkexit); 330 ATF_TEST_CASE_HEAD(timeout_forkexit) 331 { 332 set_md_var("descr", "Helper test case for the t_integration test program"); 333 } 334 ATF_TEST_CASE_BODY(timeout_forkexit) 335 { 336 pid_t pid = fork(); 337 ATF_REQUIRE(pid != -1); 338 339 if (pid == 0) { 340 sigset_t mask; 341 sigemptyset(&mask); 342 343 std::cout << "Waiting in subprocess\n"; 344 std::cout.flush(); 345 ::sigsuspend(&mask); 346 347 touch(get_config_var("statedir") + "/child-finished"); 348 std::cout << "Subprocess exiting\n"; 349 std::cout.flush(); 350 exit(EXIT_SUCCESS); 351 } else { 352 // Don't wait for the child process and let atf-run deal with it. 353 touch(get_config_var("statedir") + "/parent-finished"); 354 std::cout << "Parent process exiting\n"; 355 ATF_PASS(); 356 } 357 } 358 359 ATF_TEST_CASE(use_fs); 360 ATF_TEST_CASE_HEAD(use_fs) 361 { 362 set_md_var("descr", "Helper test case for the t_integration test program"); 363 set_md_var("use.fs", "this-is-deprecated"); 364 } 365 ATF_TEST_CASE_BODY(use_fs) 366 { 367 touch("test-file"); 368 } 369 370 // ------------------------------------------------------------------------ 371 // Main. 372 // ------------------------------------------------------------------------ 373 374 ATF_INIT_TEST_CASES(tcs) 375 { 376 std::string which = atf::env::get("TESTCASE"); 377 378 // Add helper tests for t_integration. 379 if (which == "pass") 380 ATF_ADD_TEST_CASE(tcs, pass); 381 if (which == "config") 382 ATF_ADD_TEST_CASE(tcs, config); 383 if (which == "fds") 384 ATF_ADD_TEST_CASE(tcs, fds); 385 if (which == "mux_streams") 386 ATF_ADD_TEST_CASE(tcs, mux_streams); 387 if (which == "testvar") 388 ATF_ADD_TEST_CASE(tcs, testvar); 389 if (which == "env_list") 390 ATF_ADD_TEST_CASE(tcs, env_list); 391 if (which == "env_home") 392 ATF_ADD_TEST_CASE(tcs, env_home); 393 if (which == "read_stdin") 394 ATF_ADD_TEST_CASE(tcs, read_stdin); 395 if (which == "umask") 396 ATF_ADD_TEST_CASE(tcs, umask); 397 if (which == "cleanup_states") 398 ATF_ADD_TEST_CASE(tcs, cleanup_states); 399 if (which == "cleanup_curdir") 400 ATF_ADD_TEST_CASE(tcs, cleanup_curdir); 401 if (which == "require_arch") 402 ATF_ADD_TEST_CASE(tcs, require_arch); 403 if (which == "require_config") 404 ATF_ADD_TEST_CASE(tcs, require_config); 405 if (which == "require_files") 406 ATF_ADD_TEST_CASE(tcs, require_files); 407 if (which == "require_machine") 408 ATF_ADD_TEST_CASE(tcs, require_machine); 409 if (which == "require_progs") 410 ATF_ADD_TEST_CASE(tcs, require_progs); 411 if (which == "require_user") 412 ATF_ADD_TEST_CASE(tcs, require_user); 413 if (which == "timeout") 414 ATF_ADD_TEST_CASE(tcs, timeout); 415 if (which == "timeout_forkexit") 416 ATF_ADD_TEST_CASE(tcs, timeout_forkexit); 417 if (which == "use_fs") 418 ATF_ADD_TEST_CASE(tcs, use_fs); 419 } 420