1240116Smarcel// Copyright (c) 2008 The NetBSD Foundation, Inc. 2240116Smarcel// All rights reserved. 3240116Smarcel// 4240116Smarcel// Redistribution and use in source and binary forms, with or without 5240116Smarcel// modification, are permitted provided that the following conditions 6240116Smarcel// are met: 7240116Smarcel// 1. Redistributions of source code must retain the above copyright 8240116Smarcel// notice, this list of conditions and the following disclaimer. 9240116Smarcel// 2. Redistributions in binary form must reproduce the above copyright 10240116Smarcel// notice, this list of conditions and the following disclaimer in the 11240116Smarcel// documentation and/or other materials provided with the distribution. 12240116Smarcel// 13240116Smarcel// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 14240116Smarcel// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 15240116Smarcel// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16240116Smarcel// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17240116Smarcel// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 18240116Smarcel// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19240116Smarcel// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 20240116Smarcel// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21240116Smarcel// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 22240116Smarcel// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23240116Smarcel// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 24240116Smarcel// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25240116Smarcel 26275988Sngie#include "atf-c++/detail/process.hpp" 27275988Sngie 28240116Smarcel#include <cstdlib> 29240116Smarcel#include <cstring> 30240116Smarcel 31275988Sngie#include <atf-c++.hpp> 32240116Smarcel 33275988Sngie#include "atf-c++/detail/test_helpers.hpp" 34240116Smarcel 35240116Smarcel// TODO: Testing the fork function is a huge task and I'm afraid of 36240116Smarcel// copy/pasting tons of stuff from the C version. I'd rather not do that 37240116Smarcel// until some code can be shared, which cannot happen until the C++ binding 38240116Smarcel// is cleaned by a fair amount. Instead... just rely (at the moment) on 39240116Smarcel// the system tests for the tools using this module. 40240116Smarcel 41240116Smarcel// ------------------------------------------------------------------------ 42240116Smarcel// Auxiliary functions. 43240116Smarcel// ------------------------------------------------------------------------ 44240116Smarcel 45240116Smarcelstatic 46240116Smarcelstd::size_t 47240116Smarcelarray_size(const char* const* array) 48240116Smarcel{ 49240116Smarcel std::size_t size = 0; 50240116Smarcel 51240116Smarcel for (const char* const* ptr = array; *ptr != NULL; ptr++) 52240116Smarcel size++; 53240116Smarcel 54240116Smarcel return size; 55240116Smarcel} 56240116Smarcel 57240116Smarcelstatic 58240116Smarcelatf::process::status 59240116Smarcelexec_process_helpers(const atf::tests::tc& tc, const char* helper_name) 60240116Smarcel{ 61240116Smarcel using atf::process::exec; 62240116Smarcel 63240116Smarcel std::vector< std::string > argv; 64251108Smarcel argv.push_back(get_process_helpers_path(tc, true).leaf_name()); 65240116Smarcel argv.push_back(helper_name); 66240116Smarcel 67251108Smarcel return exec(get_process_helpers_path(tc, true), 68240116Smarcel atf::process::argv_array(argv), 69240116Smarcel atf::process::stream_inherit(), 70240116Smarcel atf::process::stream_inherit()); 71240116Smarcel} 72240116Smarcel 73240116Smarcel// ------------------------------------------------------------------------ 74240116Smarcel// Tests for the "argv_array" type. 75240116Smarcel// ------------------------------------------------------------------------ 76240116Smarcel 77240116SmarcelATF_TEST_CASE(argv_array_init_carray); 78240116SmarcelATF_TEST_CASE_HEAD(argv_array_init_carray) 79240116Smarcel{ 80240116Smarcel set_md_var("descr", "Tests that argv_array is correctly constructed " 81240116Smarcel "from a C-style array of strings"); 82240116Smarcel} 83240116SmarcelATF_TEST_CASE_BODY(argv_array_init_carray) 84240116Smarcel{ 85240116Smarcel { 86240116Smarcel const char* const carray[] = { NULL }; 87240116Smarcel atf::process::argv_array argv(carray); 88240116Smarcel 89240116Smarcel ATF_REQUIRE_EQ(argv.size(), 0); 90240116Smarcel } 91240116Smarcel 92240116Smarcel { 93240116Smarcel const char* const carray[] = { "arg0", NULL }; 94240116Smarcel atf::process::argv_array argv(carray); 95240116Smarcel 96240116Smarcel ATF_REQUIRE_EQ(argv.size(), 1); 97240116Smarcel ATF_REQUIRE(std::strcmp(argv[0], carray[0]) == 0); 98240116Smarcel } 99240116Smarcel 100240116Smarcel { 101240116Smarcel const char* const carray[] = { "arg0", "arg1", "arg2", NULL }; 102240116Smarcel atf::process::argv_array argv(carray); 103240116Smarcel 104240116Smarcel ATF_REQUIRE_EQ(argv.size(), 3); 105240116Smarcel ATF_REQUIRE(std::strcmp(argv[0], carray[0]) == 0); 106240116Smarcel ATF_REQUIRE(std::strcmp(argv[1], carray[1]) == 0); 107240116Smarcel ATF_REQUIRE(std::strcmp(argv[2], carray[2]) == 0); 108240116Smarcel } 109240116Smarcel} 110240116Smarcel 111240116SmarcelATF_TEST_CASE(argv_array_init_col); 112240116SmarcelATF_TEST_CASE_HEAD(argv_array_init_col) 113240116Smarcel{ 114240116Smarcel set_md_var("descr", "Tests that argv_array is correctly constructed " 115240116Smarcel "from a string collection"); 116240116Smarcel} 117240116SmarcelATF_TEST_CASE_BODY(argv_array_init_col) 118240116Smarcel{ 119240116Smarcel { 120240116Smarcel std::vector< std::string > col; 121240116Smarcel atf::process::argv_array argv(col); 122240116Smarcel 123240116Smarcel ATF_REQUIRE_EQ(argv.size(), 0); 124240116Smarcel } 125240116Smarcel 126240116Smarcel { 127240116Smarcel std::vector< std::string > col; 128240116Smarcel col.push_back("arg0"); 129240116Smarcel atf::process::argv_array argv(col); 130240116Smarcel 131240116Smarcel ATF_REQUIRE_EQ(argv.size(), 1); 132240116Smarcel ATF_REQUIRE_EQ(argv[0], col[0]); 133240116Smarcel } 134240116Smarcel 135240116Smarcel { 136240116Smarcel std::vector< std::string > col; 137240116Smarcel col.push_back("arg0"); 138240116Smarcel col.push_back("arg1"); 139240116Smarcel col.push_back("arg2"); 140240116Smarcel atf::process::argv_array argv(col); 141240116Smarcel 142240116Smarcel ATF_REQUIRE_EQ(argv.size(), 3); 143240116Smarcel ATF_REQUIRE_EQ(argv[0], col[0]); 144240116Smarcel ATF_REQUIRE_EQ(argv[1], col[1]); 145240116Smarcel ATF_REQUIRE_EQ(argv[2], col[2]); 146240116Smarcel } 147240116Smarcel} 148240116Smarcel 149240116SmarcelATF_TEST_CASE(argv_array_init_empty); 150240116SmarcelATF_TEST_CASE_HEAD(argv_array_init_empty) 151240116Smarcel{ 152240116Smarcel set_md_var("descr", "Tests that argv_array is correctly constructed " 153240116Smarcel "by the default constructor"); 154240116Smarcel} 155240116SmarcelATF_TEST_CASE_BODY(argv_array_init_empty) 156240116Smarcel{ 157240116Smarcel atf::process::argv_array argv; 158240116Smarcel 159240116Smarcel ATF_REQUIRE_EQ(argv.size(), 0); 160240116Smarcel} 161240116Smarcel 162240116SmarcelATF_TEST_CASE(argv_array_init_varargs); 163240116SmarcelATF_TEST_CASE_HEAD(argv_array_init_varargs) 164240116Smarcel{ 165240116Smarcel set_md_var("descr", "Tests that argv_array is correctly constructed " 166240116Smarcel "from a variable list of arguments"); 167240116Smarcel} 168240116SmarcelATF_TEST_CASE_BODY(argv_array_init_varargs) 169240116Smarcel{ 170240116Smarcel { 171240116Smarcel atf::process::argv_array argv("arg0", NULL); 172240116Smarcel 173240116Smarcel ATF_REQUIRE_EQ(argv.size(), 1); 174240116Smarcel ATF_REQUIRE_EQ(argv[0], std::string("arg0")); 175240116Smarcel } 176240116Smarcel 177240116Smarcel { 178240116Smarcel atf::process::argv_array argv("arg0", "arg1", "arg2", NULL); 179240116Smarcel 180240116Smarcel ATF_REQUIRE_EQ(argv.size(), 3); 181240116Smarcel ATF_REQUIRE_EQ(argv[0], std::string("arg0")); 182240116Smarcel ATF_REQUIRE_EQ(argv[1], std::string("arg1")); 183240116Smarcel ATF_REQUIRE_EQ(argv[2], std::string("arg2")); 184240116Smarcel } 185240116Smarcel} 186240116Smarcel 187240116SmarcelATF_TEST_CASE(argv_array_assign); 188240116SmarcelATF_TEST_CASE_HEAD(argv_array_assign) 189240116Smarcel{ 190240116Smarcel set_md_var("descr", "Tests that assigning an argv_array works"); 191240116Smarcel} 192240116SmarcelATF_TEST_CASE_BODY(argv_array_assign) 193240116Smarcel{ 194240116Smarcel using atf::process::argv_array; 195240116Smarcel 196240116Smarcel const char* const carray1[] = { "arg1", NULL }; 197240116Smarcel const char* const carray2[] = { "arg1", "arg2", NULL }; 198240116Smarcel 199240116Smarcel std::auto_ptr< argv_array > argv1(new argv_array(carray1)); 200240116Smarcel std::auto_ptr< argv_array > argv2(new argv_array(carray2)); 201240116Smarcel 202240116Smarcel *argv2 = *argv1; 203240116Smarcel ATF_REQUIRE_EQ(argv2->size(), argv1->size()); 204240116Smarcel ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0); 205240116Smarcel 206240116Smarcel ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv()); 207240116Smarcel argv1.release(); 208240116Smarcel { 209240116Smarcel const char* const* eargv2 = argv2->exec_argv(); 210240116Smarcel ATF_REQUIRE(std::strcmp(eargv2[0], carray1[0]) == 0); 211240116Smarcel ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL)); 212240116Smarcel } 213240116Smarcel 214240116Smarcel argv2.release(); 215240116Smarcel} 216240116Smarcel 217240116SmarcelATF_TEST_CASE(argv_array_copy); 218240116SmarcelATF_TEST_CASE_HEAD(argv_array_copy) 219240116Smarcel{ 220240116Smarcel set_md_var("descr", "Tests that copying an argv_array constructed from " 221240116Smarcel "a C-style array of strings works"); 222240116Smarcel} 223240116SmarcelATF_TEST_CASE_BODY(argv_array_copy) 224240116Smarcel{ 225240116Smarcel using atf::process::argv_array; 226240116Smarcel 227240116Smarcel const char* const carray[] = { "arg0", NULL }; 228240116Smarcel 229240116Smarcel std::auto_ptr< argv_array > argv1(new argv_array(carray)); 230240116Smarcel std::auto_ptr< argv_array > argv2(new argv_array(*argv1)); 231240116Smarcel 232240116Smarcel ATF_REQUIRE_EQ(argv2->size(), argv1->size()); 233240116Smarcel ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0); 234240116Smarcel 235240116Smarcel ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv()); 236240116Smarcel argv1.release(); 237240116Smarcel { 238240116Smarcel const char* const* eargv2 = argv2->exec_argv(); 239240116Smarcel ATF_REQUIRE(std::strcmp(eargv2[0], carray[0]) == 0); 240240116Smarcel ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL)); 241240116Smarcel } 242240116Smarcel 243240116Smarcel argv2.release(); 244240116Smarcel} 245240116Smarcel 246240116SmarcelATF_TEST_CASE(argv_array_exec_argv); 247240116SmarcelATF_TEST_CASE_HEAD(argv_array_exec_argv) 248240116Smarcel{ 249240116Smarcel set_md_var("descr", "Tests that the exec argv provided by an argv_array " 250240116Smarcel "is correct"); 251240116Smarcel} 252240116SmarcelATF_TEST_CASE_BODY(argv_array_exec_argv) 253240116Smarcel{ 254240116Smarcel using atf::process::argv_array; 255240116Smarcel 256240116Smarcel { 257240116Smarcel argv_array argv; 258240116Smarcel const char* const* eargv = argv.exec_argv(); 259240116Smarcel ATF_REQUIRE_EQ(array_size(eargv), 0); 260240116Smarcel ATF_REQUIRE_EQ(eargv[0], static_cast< const char* >(NULL)); 261240116Smarcel } 262240116Smarcel 263240116Smarcel { 264240116Smarcel const char* const carray[] = { "arg0", NULL }; 265240116Smarcel argv_array argv(carray); 266240116Smarcel const char* const* eargv = argv.exec_argv(); 267240116Smarcel ATF_REQUIRE_EQ(array_size(eargv), 1); 268240116Smarcel ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0); 269240116Smarcel ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL)); 270240116Smarcel } 271240116Smarcel 272240116Smarcel { 273240116Smarcel std::vector< std::string > col; 274240116Smarcel col.push_back("arg0"); 275240116Smarcel argv_array argv(col); 276240116Smarcel const char* const* eargv = argv.exec_argv(); 277240116Smarcel ATF_REQUIRE_EQ(array_size(eargv), 1); 278240116Smarcel ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0); 279240116Smarcel ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL)); 280240116Smarcel } 281240116Smarcel} 282240116Smarcel 283240116SmarcelATF_TEST_CASE(argv_array_iter); 284240116SmarcelATF_TEST_CASE_HEAD(argv_array_iter) 285240116Smarcel{ 286240116Smarcel set_md_var("descr", "Tests that an argv_array can be iterated"); 287240116Smarcel} 288240116SmarcelATF_TEST_CASE_BODY(argv_array_iter) 289240116Smarcel{ 290240116Smarcel using atf::process::argv_array; 291240116Smarcel 292240116Smarcel std::vector< std::string > vector; 293240116Smarcel vector.push_back("arg0"); 294240116Smarcel vector.push_back("arg1"); 295240116Smarcel vector.push_back("arg2"); 296240116Smarcel 297240116Smarcel argv_array argv(vector); 298240116Smarcel ATF_REQUIRE_EQ(argv.size(), 3); 299240116Smarcel std::vector< std::string >::size_type pos = 0; 300240116Smarcel for (argv_array::const_iterator iter = argv.begin(); iter != argv.end(); 301240116Smarcel iter++) { 302240116Smarcel ATF_REQUIRE_EQ(*iter, vector[pos]); 303240116Smarcel pos++; 304240116Smarcel } 305240116Smarcel} 306240116Smarcel 307240116Smarcel// ------------------------------------------------------------------------ 308240116Smarcel// Tests cases for the free functions. 309240116Smarcel// ------------------------------------------------------------------------ 310240116Smarcel 311240116SmarcelATF_TEST_CASE(exec_failure); 312240116SmarcelATF_TEST_CASE_HEAD(exec_failure) 313240116Smarcel{ 314240116Smarcel set_md_var("descr", "Tests execing a command that reports failure"); 315240116Smarcel} 316240116SmarcelATF_TEST_CASE_BODY(exec_failure) 317240116Smarcel{ 318240116Smarcel const atf::process::status s = exec_process_helpers(*this, "exit-failure"); 319240116Smarcel ATF_REQUIRE(s.exited()); 320240116Smarcel ATF_REQUIRE_EQ(s.exitstatus(), EXIT_FAILURE); 321240116Smarcel} 322240116Smarcel 323240116SmarcelATF_TEST_CASE(exec_success); 324240116SmarcelATF_TEST_CASE_HEAD(exec_success) 325240116Smarcel{ 326240116Smarcel set_md_var("descr", "Tests execing a command that reports success"); 327240116Smarcel} 328240116SmarcelATF_TEST_CASE_BODY(exec_success) 329240116Smarcel{ 330240116Smarcel const atf::process::status s = exec_process_helpers(*this, "exit-success"); 331240116Smarcel ATF_REQUIRE(s.exited()); 332240116Smarcel ATF_REQUIRE_EQ(s.exitstatus(), EXIT_SUCCESS); 333240116Smarcel} 334240116Smarcel 335240116Smarcel// ------------------------------------------------------------------------ 336240116Smarcel// Main. 337240116Smarcel// ------------------------------------------------------------------------ 338240116Smarcel 339240116SmarcelATF_INIT_TEST_CASES(tcs) 340240116Smarcel{ 341240116Smarcel // Add the test cases for the "argv_array" type. 342240116Smarcel ATF_ADD_TEST_CASE(tcs, argv_array_assign); 343240116Smarcel ATF_ADD_TEST_CASE(tcs, argv_array_copy); 344240116Smarcel ATF_ADD_TEST_CASE(tcs, argv_array_exec_argv); 345240116Smarcel ATF_ADD_TEST_CASE(tcs, argv_array_init_carray); 346240116Smarcel ATF_ADD_TEST_CASE(tcs, argv_array_init_col); 347240116Smarcel ATF_ADD_TEST_CASE(tcs, argv_array_init_empty); 348240116Smarcel ATF_ADD_TEST_CASE(tcs, argv_array_init_varargs); 349240116Smarcel ATF_ADD_TEST_CASE(tcs, argv_array_iter); 350240116Smarcel 351240116Smarcel // Add the test cases for the free functions. 352240116Smarcel ATF_ADD_TEST_CASE(tcs, exec_failure); 353240116Smarcel ATF_ADD_TEST_CASE(tcs, exec_success); 354240116Smarcel} 355