Path: blob/main/contrib/atf/atf-c++/check_test.cpp
39507 views
// Copyright (c) 2007 The NetBSD Foundation, Inc.1// All rights reserved.2//3// Redistribution and use in source and binary forms, with or without4// modification, are permitted provided that the following conditions5// are met:6// 1. Redistributions of source code must retain the above copyright7// notice, this list of conditions and the following disclaimer.8// 2. Redistributions in binary form must reproduce the above copyright9// notice, this list of conditions and the following disclaimer in the10// documentation and/or other materials provided with the distribution.11//12// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND13// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,14// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF15// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.16// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY17// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE19// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS20// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER21// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR22// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN23// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.2425#include "atf-c++/check.hpp"2627extern "C" {28#include <fcntl.h>29#include <signal.h>30#include <unistd.h>31}3233#include <cstdlib>34#include <cstring>35#include <fstream>36#include <iostream>37#include <list>38#include <memory>39#include <vector>4041#include <atf-c++.hpp>4243#include "atf-c++/detail/fs.hpp"44#include "atf-c++/detail/process.hpp"45#include "atf-c++/detail/test_helpers.hpp"46#include "atf-c++/detail/text.hpp"47#include "atf-c++/utils.hpp"4849// ------------------------------------------------------------------------50// Auxiliary functions.51// ------------------------------------------------------------------------5253static54std::unique_ptr< atf::check::check_result >55do_exec(const atf::tests::tc* tc, const char* helper_name)56{57std::vector< std::string > argv;58argv.push_back(get_process_helpers_path(*tc, false).str());59argv.push_back(helper_name);60std::cout << "Executing " << argv[0] << " " << argv[1] << "\n";6162atf::process::argv_array argva(argv);63return atf::check::exec(argva);64}6566static67std::unique_ptr< atf::check::check_result >68do_exec(const atf::tests::tc* tc, const char* helper_name, const char *carg2)69{70std::vector< std::string > argv;71argv.push_back(get_process_helpers_path(*tc, false).str());72argv.push_back(helper_name);73argv.push_back(carg2);74std::cout << "Executing " << argv[0] << " " << argv[1] << " "75<< argv[2] << "\n";7677atf::process::argv_array argva(argv);78return atf::check::exec(argva);79}8081// ------------------------------------------------------------------------82// Helper test cases for the free functions.83// ------------------------------------------------------------------------8485ATF_TEST_CASE(h_build_c_o_ok);86ATF_TEST_CASE_HEAD(h_build_c_o_ok)87{88set_md_var("descr", "Helper test case for build_c_o");89}90ATF_TEST_CASE_BODY(h_build_c_o_ok)91{92std::ofstream sfile("test.c");93sfile << "#include <stdio.h>\n";94sfile.close();9596ATF_REQUIRE(atf::check::build_c_o("test.c", "test.o",97atf::process::argv_array()));98}99100ATF_TEST_CASE(h_build_c_o_fail);101ATF_TEST_CASE_HEAD(h_build_c_o_fail)102{103set_md_var("descr", "Helper test case for build_c_o");104}105ATF_TEST_CASE_BODY(h_build_c_o_fail)106{107std::ofstream sfile("test.c");108sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";109sfile.close();110111ATF_REQUIRE(!atf::check::build_c_o("test.c", "test.o",112atf::process::argv_array()));113}114115ATF_TEST_CASE(h_build_cpp_ok);116ATF_TEST_CASE_HEAD(h_build_cpp_ok)117{118set_md_var("descr", "Helper test case for build_cpp");119}120ATF_TEST_CASE_BODY(h_build_cpp_ok)121{122std::ofstream sfile("test.c");123sfile << "#define A foo\n";124sfile << "#define B bar\n";125sfile << "A B\n";126sfile.close();127128ATF_REQUIRE(atf::check::build_cpp("test.c", "test.p",129atf::process::argv_array()));130}131132ATF_TEST_CASE(h_build_cpp_fail);133ATF_TEST_CASE_HEAD(h_build_cpp_fail)134{135set_md_var("descr", "Helper test case for build_cpp");136}137ATF_TEST_CASE_BODY(h_build_cpp_fail)138{139std::ofstream sfile("test.c");140sfile << "#include \"./non-existent.h\"\n";141sfile.close();142143ATF_REQUIRE(!atf::check::build_cpp("test.c", "test.p",144atf::process::argv_array()));145}146147ATF_TEST_CASE(h_build_cxx_o_ok);148ATF_TEST_CASE_HEAD(h_build_cxx_o_ok)149{150set_md_var("descr", "Helper test case for build_cxx_o");151}152ATF_TEST_CASE_BODY(h_build_cxx_o_ok)153{154std::ofstream sfile("test.cpp");155sfile << "#include <iostream>\n";156sfile.close();157158ATF_REQUIRE(atf::check::build_cxx_o("test.cpp", "test.o",159atf::process::argv_array()));160}161162ATF_TEST_CASE(h_build_cxx_o_fail);163ATF_TEST_CASE_HEAD(h_build_cxx_o_fail)164{165set_md_var("descr", "Helper test case for build_cxx_o");166}167ATF_TEST_CASE_BODY(h_build_cxx_o_fail)168{169std::ofstream sfile("test.cpp");170sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";171sfile.close();172173ATF_REQUIRE(!atf::check::build_cxx_o("test.cpp", "test.o",174atf::process::argv_array()));175}176177// ------------------------------------------------------------------------178// Test cases for the free functions.179// ------------------------------------------------------------------------180181ATF_TEST_CASE(build_c_o);182ATF_TEST_CASE_HEAD(build_c_o)183{184set_md_var("descr", "Tests the build_c_o function");185}186ATF_TEST_CASE_BODY(build_c_o)187{188ATF_TEST_CASE_USE(h_build_c_o_ok);189run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_ok) >();190ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));191ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));192193ATF_TEST_CASE_USE(h_build_c_o_fail);194run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_fail) >();195ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));196ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));197ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));198ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));199}200201ATF_TEST_CASE(build_cpp);202ATF_TEST_CASE_HEAD(build_cpp)203{204set_md_var("descr", "Tests the build_cpp function");205}206ATF_TEST_CASE_BODY(build_cpp)207{208ATF_TEST_CASE_USE(h_build_cpp_ok);209run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_ok) >();210ATF_REQUIRE(atf::utils::grep_file("-o.*test.p", "stdout"));211ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));212ATF_REQUIRE(atf::utils::grep_file("foo bar", "test.p"));213214ATF_TEST_CASE_USE(h_build_cpp_fail);215run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_fail) >();216ATF_REQUIRE(atf::utils::grep_file("-o test.p", "stdout"));217ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));218ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));219ATF_REQUIRE(atf::utils::grep_file("non-existent.h", "stderr"));220}221222ATF_TEST_CASE(build_cxx_o);223ATF_TEST_CASE_HEAD(build_cxx_o)224{225set_md_var("descr", "Tests the build_cxx_o function");226}227ATF_TEST_CASE_BODY(build_cxx_o)228{229ATF_TEST_CASE_USE(h_build_cxx_o_ok);230run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_ok) >();231ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));232ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));233234ATF_TEST_CASE_USE(h_build_cxx_o_fail);235run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_fail) >();236ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));237ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));238ATF_REQUIRE(atf::utils::grep_file("test.cpp", "stderr"));239ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));240}241242ATF_TEST_CASE(exec_cleanup);243ATF_TEST_CASE_HEAD(exec_cleanup)244{245set_md_var("descr", "Tests that exec properly cleans up the temporary "246"files it creates");247}248ATF_TEST_CASE_BODY(exec_cleanup)249{250std::unique_ptr< atf::fs::path > out;251std::unique_ptr< atf::fs::path > err;252253{254std::unique_ptr< atf::check::check_result > r =255do_exec(this, "exit-success");256out.reset(new atf::fs::path(r->stdout_path()));257err.reset(new atf::fs::path(r->stderr_path()));258ATF_REQUIRE(atf::fs::exists(*out.get()));259ATF_REQUIRE(atf::fs::exists(*err.get()));260}261ATF_REQUIRE(!atf::fs::exists(*out.get()));262ATF_REQUIRE(!atf::fs::exists(*err.get()));263}264265ATF_TEST_CASE(exec_exitstatus);266ATF_TEST_CASE_HEAD(exec_exitstatus)267{268set_md_var("descr", "Tests that exec properly captures the exit "269"status of the executed command");270}271ATF_TEST_CASE_BODY(exec_exitstatus)272{273{274std::unique_ptr< atf::check::check_result > r =275do_exec(this, "exit-success");276ATF_REQUIRE(r->exited());277ATF_REQUIRE(!r->signaled());278ATF_REQUIRE_EQ(r->exitcode(), EXIT_SUCCESS);279}280281{282std::unique_ptr< atf::check::check_result > r =283do_exec(this, "exit-failure");284ATF_REQUIRE(r->exited());285ATF_REQUIRE(!r->signaled());286ATF_REQUIRE_EQ(r->exitcode(), EXIT_FAILURE);287}288289{290std::unique_ptr< atf::check::check_result > r =291do_exec(this, "exit-signal");292ATF_REQUIRE(!r->exited());293ATF_REQUIRE(r->signaled());294ATF_REQUIRE_EQ(r->termsig(), SIGKILL);295}296}297298static299void300check_lines(const std::string& path, const char* outname,301const char* resname)302{303std::ifstream f(path.c_str());304ATF_REQUIRE(f);305306std::string line;307std::getline(f, line);308ATF_REQUIRE_EQ(line, std::string("Line 1 to ") + outname + " for " +309resname);310std::getline(f, line);311ATF_REQUIRE_EQ(line, std::string("Line 2 to ") + outname + " for " +312resname);313}314315ATF_TEST_CASE(exec_stdout_stderr);316ATF_TEST_CASE_HEAD(exec_stdout_stderr)317{318set_md_var("descr", "Tests that exec properly captures the stdout "319"and stderr streams of the child process");320}321ATF_TEST_CASE_BODY(exec_stdout_stderr)322{323std::unique_ptr< atf::check::check_result > r1 =324do_exec(this, "stdout-stderr", "result1");325ATF_REQUIRE(r1->exited());326ATF_REQUIRE_EQ(r1->exitcode(), EXIT_SUCCESS);327328std::unique_ptr< atf::check::check_result > r2 =329do_exec(this, "stdout-stderr", "result2");330ATF_REQUIRE(r2->exited());331ATF_REQUIRE_EQ(r2->exitcode(), EXIT_SUCCESS);332333const std::string out1 = r1->stdout_path();334const std::string out2 = r2->stdout_path();335const std::string err1 = r1->stderr_path();336const std::string err2 = r2->stderr_path();337338ATF_REQUIRE(out1.find("check.XXXXXX") == std::string::npos);339ATF_REQUIRE(out2.find("check.XXXXXX") == std::string::npos);340ATF_REQUIRE(err1.find("check.XXXXXX") == std::string::npos);341ATF_REQUIRE(err2.find("check.XXXXXX") == std::string::npos);342343ATF_REQUIRE(out1.find("/check") != std::string::npos);344ATF_REQUIRE(out2.find("/check") != std::string::npos);345ATF_REQUIRE(err1.find("/check") != std::string::npos);346ATF_REQUIRE(err2.find("/check") != std::string::npos);347348ATF_REQUIRE(out1.find("/stdout") != std::string::npos);349ATF_REQUIRE(out2.find("/stdout") != std::string::npos);350ATF_REQUIRE(err1.find("/stderr") != std::string::npos);351ATF_REQUIRE(err2.find("/stderr") != std::string::npos);352353ATF_REQUIRE(out1 != out2);354ATF_REQUIRE(err1 != err2);355356check_lines(out1, "stdout", "result1");357check_lines(out2, "stdout", "result2");358check_lines(err1, "stderr", "result1");359check_lines(err2, "stderr", "result2");360}361362ATF_TEST_CASE(exec_unknown);363ATF_TEST_CASE_HEAD(exec_unknown)364{365set_md_var("descr", "Tests that running a non-existing binary "366"is handled correctly");367}368ATF_TEST_CASE_BODY(exec_unknown)369{370std::vector< std::string > argv;371argv.push_back("/foo/bar/non-existent");372373atf::process::argv_array argva(argv);374std::unique_ptr< atf::check::check_result > r = atf::check::exec(argva);375ATF_REQUIRE(r->exited());376ATF_REQUIRE_EQ(r->exitcode(), 127);377}378379// ------------------------------------------------------------------------380// Main.381// ------------------------------------------------------------------------382383ATF_INIT_TEST_CASES(tcs)384{385// Add the test cases for the free functions.386ATF_ADD_TEST_CASE(tcs, build_c_o);387ATF_ADD_TEST_CASE(tcs, build_cpp);388ATF_ADD_TEST_CASE(tcs, build_cxx_o);389ATF_ADD_TEST_CASE(tcs, exec_cleanup);390ATF_ADD_TEST_CASE(tcs, exec_exitstatus);391ATF_ADD_TEST_CASE(tcs, exec_stdout_stderr);392ATF_ADD_TEST_CASE(tcs, exec_unknown);393}394395396