143412Snewton// 243412Snewton// Automated Testing Framework (atf) 343412Snewton// 443412Snewton// Copyright (c) 2007 The NetBSD Foundation, Inc. 543412Snewton// All rights reserved. 643412Snewton// 743412Snewton// Redistribution and use in source and binary forms, with or without 843412Snewton// modification, are permitted provided that the following conditions 943412Snewton// are met: 1043412Snewton// 1. Redistributions of source code must retain the above copyright 1143412Snewton// notice, this list of conditions and the following disclaimer. 1243412Snewton// 2. Redistributions in binary form must reproduce the above copyright 1343412Snewton// notice, this list of conditions and the following disclaimer in the 1443412Snewton// documentation and/or other materials provided with the distribution. 1543412Snewton// 1643412Snewton// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 1743412Snewton// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 1843412Snewton// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1943412Snewton// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2043412Snewton// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 2143412Snewton// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2243412Snewton// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 2343412Snewton// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2443412Snewton// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 2543412Snewton// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2643412Snewton// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 2743412Snewton// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2843412Snewton// 2943412Snewton 3043412Snewtonextern "C" { 3143412Snewton#include <fcntl.h> 3243412Snewton#include <signal.h> 3343412Snewton#include <unistd.h> 3443412Snewton} 3543412Snewton 36139743Simp#include <cstdlib> 3743412Snewton#include <cstring> 3843412Snewton#include <fstream> 3943412Snewton#include <iostream> 4043412Snewton#include <list> 4143412Snewton#include <memory> 4243412Snewton#include <vector> 4343412Snewton 4443412Snewton#include <atf-c++.hpp> 4543412Snewton 4643412Snewton#include "check.hpp" 4743412Snewton#include "config.hpp" 4843412Snewton#include "utils.hpp" 4943412Snewton 5043412Snewton#include "detail/fs.hpp" 5143412Snewton#include "detail/process.hpp" 5243412Snewton#include "detail/test_helpers.hpp" 5343412Snewton#include "detail/text.hpp" 5443412Snewton 5543412Snewton// ------------------------------------------------------------------------ 5643412Snewton// Auxiliary functions. 5743412Snewton// ------------------------------------------------------------------------ 5843412Snewton 5943412Snewtonstatic 6043412Snewtonstd::auto_ptr< atf::check::check_result > 6143412Snewtondo_exec(const atf::tests::tc* tc, const char* helper_name) 6243412Snewton{ 6343412Snewton std::vector< std::string > argv; 6443412Snewton argv.push_back(get_process_helpers_path(*tc, false).str()); 6543412Snewton argv.push_back(helper_name); 6643412Snewton std::cout << "Executing " << argv[0] << " " << argv[1] << "\n"; 6743412Snewton 6843412Snewton atf::process::argv_array argva(argv); 6943412Snewton return atf::check::exec(argva); 70116174Sobrien} 7143412Snewton 7243412Snewtonstatic 73116174Sobrienstd::auto_ptr< atf::check::check_result > 74116174Sobriendo_exec(const atf::tests::tc* tc, const char* helper_name, const char *carg2) 75116174Sobrien{ 76147817Sjhb std::vector< std::string > argv; 77147817Sjhb argv.push_back(get_process_helpers_path(*tc, false).str()); 7843412Snewton argv.push_back(helper_name); 79147817Sjhb argv.push_back(carg2); 80147817Sjhb std::cout << "Executing " << argv[0] << " " << argv[1] << " " 8143412Snewton << argv[2] << "\n"; 82147817Sjhb 83147817Sjhb atf::process::argv_array argva(argv); 84147817Sjhb return atf::check::exec(argva); 85147817Sjhb} 86147817Sjhb 8743412Snewton// ------------------------------------------------------------------------ 8843412Snewton// Helper test cases for the free functions. 8965302Sobrien// ------------------------------------------------------------------------ 9065302Sobrien 9165302SobrienATF_TEST_CASE(h_build_c_o_ok); 9265302SobrienATF_TEST_CASE_HEAD(h_build_c_o_ok) 9365302Sobrien{ 9465302Sobrien set_md_var("descr", "Helper test case for build_c_o"); 9543412Snewton} 9643412SnewtonATF_TEST_CASE_BODY(h_build_c_o_ok) 9792761Salfred{ 9892761Salfred std::ofstream sfile("test.c"); 9992761Salfred sfile << "#include <stdio.h>\n"; 10092761Salfred sfile.close(); 10143412Snewton 10243412Snewton ATF_REQUIRE(atf::check::build_c_o("test.c", "test.o", 10343412Snewton atf::process::argv_array())); 10492761Salfred} 10592761Salfred 10692761SalfredATF_TEST_CASE(h_build_c_o_fail); 10792761SalfredATF_TEST_CASE_HEAD(h_build_c_o_fail) 10892761Salfred{ 10992761Salfred set_md_var("descr", "Helper test case for build_c_o"); 110147817Sjhb} 111147817SjhbATF_TEST_CASE_BODY(h_build_c_o_fail) 112147817Sjhb{ 11343412Snewton std::ofstream sfile("test.c"); 11443412Snewton sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n"; 11543412Snewton sfile.close(); 11692761Salfred 11792761Salfred ATF_REQUIRE(!atf::check::build_c_o("test.c", "test.o", 11892761Salfred atf::process::argv_array())); 11992761Salfred} 120147817Sjhb 121147817SjhbATF_TEST_CASE(h_build_cpp_ok); 122147817SjhbATF_TEST_CASE_HEAD(h_build_cpp_ok) 123147817Sjhb{ 12443412Snewton set_md_var("descr", "Helper test case for build_cpp"); 12543412Snewton} 12643412SnewtonATF_TEST_CASE_BODY(h_build_cpp_ok) 12792761Salfred{ 12892761Salfred std::ofstream sfile("test.c"); 12992761Salfred sfile << "#define A foo\n"; 13092761Salfred sfile << "#define B bar\n"; 131147817Sjhb sfile << "A B\n"; 132147817Sjhb sfile.close(); 133147817Sjhb 134147817Sjhb ATF_REQUIRE(atf::check::build_cpp("test.c", "test.p", 13543412Snewton atf::process::argv_array())); 13643412Snewton} 13743412Snewton 13843412SnewtonATF_TEST_CASE(h_build_cpp_fail); 13943412SnewtonATF_TEST_CASE_HEAD(h_build_cpp_fail) 14043412Snewton{ 14143412Snewton set_md_var("descr", "Helper test case for build_cpp"); 14243412Snewton} 14343412SnewtonATF_TEST_CASE_BODY(h_build_cpp_fail) 14443412Snewton{ 14543412Snewton std::ofstream sfile("test.c"); 14643412Snewton sfile << "#include \"./non-existent.h\"\n"; 14743412Snewton sfile.close(); 14843412Snewton 14943412Snewton ATF_REQUIRE(!atf::check::build_cpp("test.c", "test.p", 15043412Snewton atf::process::argv_array())); 15143412Snewton} 15243412Snewton 15343412SnewtonATF_TEST_CASE(h_build_cxx_o_ok); 15443412SnewtonATF_TEST_CASE_HEAD(h_build_cxx_o_ok) 15543412Snewton{ 15643412Snewton set_md_var("descr", "Helper test case for build_cxx_o"); 15743412Snewton} 15843412SnewtonATF_TEST_CASE_BODY(h_build_cxx_o_ok) 15943412Snewton{ 16043412Snewton std::ofstream sfile("test.cpp"); 16143412Snewton sfile << "#include <iostream>\n"; 16243412Snewton sfile.close(); 16343412Snewton 16443412Snewton ATF_REQUIRE(atf::check::build_cxx_o("test.cpp", "test.o", 16543412Snewton atf::process::argv_array())); 16643412Snewton} 16743412Snewton 16843412SnewtonATF_TEST_CASE(h_build_cxx_o_fail); 16943412SnewtonATF_TEST_CASE_HEAD(h_build_cxx_o_fail) 17043412Snewton{ 17143412Snewton set_md_var("descr", "Helper test case for build_cxx_o"); 17243412Snewton} 17343412SnewtonATF_TEST_CASE_BODY(h_build_cxx_o_fail) 17443412Snewton{ 17543412Snewton std::ofstream sfile("test.cpp"); 17643412Snewton sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n"; 17743412Snewton sfile.close(); 17843412Snewton 17943412Snewton ATF_REQUIRE(!atf::check::build_cxx_o("test.cpp", "test.o", 18043412Snewton atf::process::argv_array())); 18143412Snewton} 18243412Snewton 18343412Snewton// ------------------------------------------------------------------------ 18443412Snewton// Test cases for the free functions. 18543412Snewton// ------------------------------------------------------------------------ 18643412Snewton 18743412SnewtonATF_TEST_CASE(build_c_o); 18843412SnewtonATF_TEST_CASE_HEAD(build_c_o) 18943412Snewton{ 19043412Snewton set_md_var("descr", "Tests the build_c_o function"); 19143412Snewton} 19243412SnewtonATF_TEST_CASE_BODY(build_c_o) 19343412Snewton{ 19443412Snewton ATF_TEST_CASE_USE(h_build_c_o_ok); 19543412Snewton run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_ok) >(); 19643412Snewton ATF_REQUIRE(grep_file("stdout", "-o test.o")); 19743412Snewton ATF_REQUIRE(grep_file("stdout", "-c test.c")); 19843412Snewton 19943412Snewton ATF_TEST_CASE_USE(h_build_c_o_fail); 20043412Snewton run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_fail) >(); 20143412Snewton ATF_REQUIRE(grep_file("stdout", "-o test.o")); 20243412Snewton ATF_REQUIRE(grep_file("stdout", "-c test.c")); 20343412Snewton ATF_REQUIRE(grep_file("stderr", "test.c")); 20443412Snewton ATF_REQUIRE(grep_file("stderr", "UNDEFINED_SYMBOL")); 20543412Snewton} 20643412Snewton 20743412SnewtonATF_TEST_CASE(build_cpp); 208147817SjhbATF_TEST_CASE_HEAD(build_cpp) 209147817Sjhb{ 210147817Sjhb set_md_var("descr", "Tests the build_cpp function"); 211147817Sjhb} 212147817SjhbATF_TEST_CASE_BODY(build_cpp) 21343412Snewton{ 21443412Snewton ATF_TEST_CASE_USE(h_build_cpp_ok); 21543412Snewton run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_ok) >(); 216147817Sjhb ATF_REQUIRE(grep_file("stdout", "-o.*test.p")); 217147817Sjhb ATF_REQUIRE(grep_file("stdout", "test.c")); 21843412Snewton ATF_REQUIRE(grep_file("test.p", "foo bar")); 21943412Snewton 22043412Snewton ATF_TEST_CASE_USE(h_build_cpp_fail); 22143412Snewton run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_fail) >(); 222147817Sjhb ATF_REQUIRE(grep_file("stdout", "-o test.p")); 22343412Snewton ATF_REQUIRE(grep_file("stdout", "test.c")); 22443412Snewton ATF_REQUIRE(grep_file("stderr", "test.c")); 22571447Sjhb ATF_REQUIRE(grep_file("stderr", "non-existent.h")); 22643412Snewton} 227107849Salfred 228107849SalfredATF_TEST_CASE(build_cxx_o); 22943412SnewtonATF_TEST_CASE_HEAD(build_cxx_o) 230107849Salfred{ 23143412Snewton set_md_var("descr", "Tests the build_cxx_o function"); 23243412Snewton} 23343412SnewtonATF_TEST_CASE_BODY(build_cxx_o) 23443412Snewton{ 235107849Salfred ATF_TEST_CASE_USE(h_build_cxx_o_ok); 23643412Snewton run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_ok) >(); 237107849Salfred ATF_REQUIRE(grep_file("stdout", "-o test.o")); 23843412Snewton ATF_REQUIRE(grep_file("stdout", "-c test.cpp")); 23943412Snewton 240107849Salfred ATF_TEST_CASE_USE(h_build_cxx_o_fail); 24143412Snewton run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_fail) >(); 24243412Snewton ATF_REQUIRE(grep_file("stdout", "-o test.o")); 243107849Salfred ATF_REQUIRE(grep_file("stdout", "-c test.cpp")); 24443412Snewton ATF_REQUIRE(grep_file("stderr", "test.cpp")); 24543412Snewton ATF_REQUIRE(grep_file("stderr", "UNDEFINED_SYMBOL")); 246107849Salfred} 24743412Snewton 24843412SnewtonATF_TEST_CASE(exec_cleanup); 249147817SjhbATF_TEST_CASE_HEAD(exec_cleanup) 25043412Snewton{ 25143412Snewton set_md_var("descr", "Tests that exec properly cleans up the temporary " 252107849Salfred "files it creates"); 25343412Snewton} 25443412SnewtonATF_TEST_CASE_BODY(exec_cleanup) 255107849Salfred{ 256147817Sjhb std::auto_ptr< atf::fs::path > out; 25743412Snewton std::auto_ptr< atf::fs::path > err; 25843412Snewton 259107849Salfred { 26043412Snewton std::auto_ptr< atf::check::check_result > r = 26143412Snewton do_exec(this, "exit-success"); 262107849Salfred out.reset(new atf::fs::path(r->stdout_path())); 263147817Sjhb err.reset(new atf::fs::path(r->stderr_path())); 26443412Snewton ATF_REQUIRE(atf::fs::exists(*out.get())); 26543412Snewton ATF_REQUIRE(atf::fs::exists(*err.get())); 266107849Salfred } 26743412Snewton ATF_REQUIRE(!atf::fs::exists(*out.get())); 26843412Snewton ATF_REQUIRE(!atf::fs::exists(*err.get())); 269107849Salfred} 270147817Sjhb 27143412SnewtonATF_TEST_CASE(exec_exitstatus); 27243412SnewtonATF_TEST_CASE_HEAD(exec_exitstatus) 273107849Salfred{ 27443412Snewton set_md_var("descr", "Tests that exec properly captures the exit " 275107849Salfred "status of the executed command"); 27643412Snewton} 27743412SnewtonATF_TEST_CASE_BODY(exec_exitstatus) 27843412Snewton{ 279147817Sjhb { 28043412Snewton std::auto_ptr< atf::check::check_result > r = 28143412Snewton do_exec(this, "exit-success"); 28243412Snewton ATF_REQUIRE(r->exited()); 28343412Snewton ATF_REQUIRE(!r->signaled()); 28443412Snewton ATF_REQUIRE_EQ(r->exitcode(), EXIT_SUCCESS); 285107849Salfred } 28643412Snewton 28743412Snewton { 288107849Salfred std::auto_ptr< atf::check::check_result > r = 28943412Snewton do_exec(this, "exit-failure"); 290107849Salfred ATF_REQUIRE(r->exited()); 29143412Snewton ATF_REQUIRE(!r->signaled()); 29243412Snewton ATF_REQUIRE_EQ(r->exitcode(), EXIT_FAILURE); 29343412Snewton } 294107849Salfred 29543412Snewton { 29643412Snewton std::auto_ptr< atf::check::check_result > r = 29743412Snewton do_exec(this, "exit-signal"); 29843412Snewton ATF_REQUIRE(!r->exited()); 29943412Snewton ATF_REQUIRE(r->signaled()); 30043412Snewton ATF_REQUIRE_EQ(r->termsig(), SIGKILL); 301147817Sjhb } 30243412Snewton} 30343412Snewton 304107849Salfredstatic 30543412Snewtonvoid 306107849Salfredcheck_lines(const std::string& path, const char* outname, 30743412Snewton const char* resname) 30843412Snewton{ 30943412Snewton std::ifstream f(path.c_str()); 310107849Salfred ATF_REQUIRE(f); 31143412Snewton 31243412Snewton std::string line; 31343412Snewton std::getline(f, line); 31443412Snewton ATF_REQUIRE_EQ(line, std::string("Line 1 to ") + outname + " for " + 31543412Snewton resname); 31643412Snewton std::getline(f, line); 317147817Sjhb ATF_REQUIRE_EQ(line, std::string("Line 2 to ") + outname + " for " + 31843412Snewton resname); 31943412Snewton} 32043412Snewton 32143412SnewtonATF_TEST_CASE(exec_stdout_stderr); 32243412SnewtonATF_TEST_CASE_HEAD(exec_stdout_stderr) 32343412Snewton{ 32443412Snewton set_md_var("descr", "Tests that exec properly captures the stdout " 325147817Sjhb "and stderr streams of the child process"); 326147817Sjhb} 327147817SjhbATF_TEST_CASE_BODY(exec_stdout_stderr) 328147817Sjhb{ 32943412Snewton std::auto_ptr< atf::check::check_result > r1 = 33043412Snewton do_exec(this, "stdout-stderr", "result1"); 33143412Snewton ATF_REQUIRE(r1->exited()); 332147817Sjhb ATF_REQUIRE_EQ(r1->exitcode(), EXIT_SUCCESS); 333147817Sjhb 33443412Snewton std::auto_ptr< atf::check::check_result > r2 = 33543412Snewton do_exec(this, "stdout-stderr", "result2"); 33643412Snewton ATF_REQUIRE(r2->exited()); 337147817Sjhb ATF_REQUIRE_EQ(r2->exitcode(), EXIT_SUCCESS); 33843412Snewton 339107849Salfred const std::string out1 = r1->stdout_path(); 340107849Salfred const std::string out2 = r2->stdout_path(); 341107849Salfred const std::string err1 = r1->stderr_path(); 34243412Snewton const std::string err2 = r2->stderr_path(); 343147817Sjhb 34443412Snewton ATF_REQUIRE(out1.find("check.XXXXXX") == std::string::npos); 34543412Snewton ATF_REQUIRE(out2.find("check.XXXXXX") == std::string::npos); 34643412Snewton ATF_REQUIRE(err1.find("check.XXXXXX") == std::string::npos); 347147817Sjhb ATF_REQUIRE(err2.find("check.XXXXXX") == std::string::npos); 348147817Sjhb 349147817Sjhb ATF_REQUIRE(out1.find("/check") != std::string::npos); 350147817Sjhb ATF_REQUIRE(out2.find("/check") != std::string::npos); 35143412Snewton ATF_REQUIRE(err1.find("/check") != std::string::npos); 35243412Snewton ATF_REQUIRE(err2.find("/check") != std::string::npos); 35343412Snewton 354147817Sjhb ATF_REQUIRE(out1.find("/stdout") != std::string::npos); 355147817Sjhb ATF_REQUIRE(out2.find("/stdout") != std::string::npos); 35643412Snewton ATF_REQUIRE(err1.find("/stderr") != std::string::npos); 35743412Snewton ATF_REQUIRE(err2.find("/stderr") != std::string::npos); 35843412Snewton 359147817Sjhb ATF_REQUIRE(out1 != out2); 36043412Snewton ATF_REQUIRE(err1 != err2); 361107849Salfred 36243412Snewton check_lines(out1, "stdout", "result1"); 363107849Salfred check_lines(out2, "stdout", "result2"); 364107849Salfred check_lines(err1, "stderr", "result1"); 36543412Snewton check_lines(err2, "stderr", "result2"); 366147817Sjhb} 36743412Snewton 36843412SnewtonATF_TEST_CASE(exec_unknown); 36943412SnewtonATF_TEST_CASE_HEAD(exec_unknown) 370147817Sjhb{ 371147817Sjhb set_md_var("descr", "Tests that running a non-existing binary " 372147817Sjhb "is handled correctly"); 37343412Snewton} 37443412SnewtonATF_TEST_CASE_BODY(exec_unknown) 375107849Salfred{ 37643412Snewton std::vector< std::string > argv; 377107849Salfred argv.push_back(atf::config::get("atf_workdir") + "/non-existent"); 37843412Snewton 379147817Sjhb atf::process::argv_array argva(argv); 38043412Snewton std::auto_ptr< atf::check::check_result > r = atf::check::exec(argva); 381147817Sjhb ATF_REQUIRE(r->exited()); 38243412Snewton ATF_REQUIRE_EQ(r->exitcode(), 127); 383147817Sjhb} 38443412Snewton 38543412Snewton// ------------------------------------------------------------------------ 38643412Snewton// Tests cases for the header file. 38743412Snewton// ------------------------------------------------------------------------ 388148541Sjhb 389148541SjhbHEADER_TC(include, "atf-c++/check.hpp"); 39043412Snewton 39143412Snewton// ------------------------------------------------------------------------ 39243412Snewton// Main. 39343412Snewton// ------------------------------------------------------------------------ 39443412Snewton 39543412SnewtonATF_INIT_TEST_CASES(tcs) 39643412Snewton{ 39743412Snewton // Add the test cases for the free functions. 39843412Snewton ATF_ADD_TEST_CASE(tcs, build_c_o); 39943412Snewton ATF_ADD_TEST_CASE(tcs, build_cpp); 40043412Snewton ATF_ADD_TEST_CASE(tcs, build_cxx_o); 40143412Snewton ATF_ADD_TEST_CASE(tcs, exec_cleanup); 40243412Snewton ATF_ADD_TEST_CASE(tcs, exec_exitstatus); 40343412Snewton ATF_ADD_TEST_CASE(tcs, exec_stdout_stderr); 40443412Snewton ATF_ADD_TEST_CASE(tcs, exec_unknown); 40543412Snewton 40643412Snewton // Add the test cases for the header file. 40743412Snewton ATF_ADD_TEST_CASE(tcs, include); 40843412Snewton} 40943412Snewton