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