process_test.cpp revision 275988
1// Copyright (c) 2008 The NetBSD Foundation, Inc. 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions 6// are met: 7// 1. Redistributions of source code must retain the above copyright 8// notice, this list of conditions and the following disclaimer. 9// 2. Redistributions in binary form must reproduce the above copyright 10// notice, this list of conditions and the following disclaimer in the 11// documentation and/or other materials provided with the distribution. 12// 13// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 14// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 15// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 18// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 20// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 22// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 24// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26#include "atf-c++/detail/process.hpp" 27 28#include <cstdlib> 29#include <cstring> 30 31#include <atf-c++.hpp> 32 33#include "atf-c++/detail/test_helpers.hpp" 34 35// TODO: Testing the fork function is a huge task and I'm afraid of 36// copy/pasting tons of stuff from the C version. I'd rather not do that 37// until some code can be shared, which cannot happen until the C++ binding 38// is cleaned by a fair amount. Instead... just rely (at the moment) on 39// the system tests for the tools using this module. 40 41// ------------------------------------------------------------------------ 42// Auxiliary functions. 43// ------------------------------------------------------------------------ 44 45static 46std::size_t 47array_size(const char* const* array) 48{ 49 std::size_t size = 0; 50 51 for (const char* const* ptr = array; *ptr != NULL; ptr++) 52 size++; 53 54 return size; 55} 56 57static 58atf::process::status 59exec_process_helpers(const atf::tests::tc& tc, const char* helper_name) 60{ 61 using atf::process::exec; 62 63 std::vector< std::string > argv; 64 argv.push_back(get_process_helpers_path(tc, true).leaf_name()); 65 argv.push_back(helper_name); 66 67 return exec(get_process_helpers_path(tc, true), 68 atf::process::argv_array(argv), 69 atf::process::stream_inherit(), 70 atf::process::stream_inherit()); 71} 72 73// ------------------------------------------------------------------------ 74// Tests for the "argv_array" type. 75// ------------------------------------------------------------------------ 76 77ATF_TEST_CASE(argv_array_init_carray); 78ATF_TEST_CASE_HEAD(argv_array_init_carray) 79{ 80 set_md_var("descr", "Tests that argv_array is correctly constructed " 81 "from a C-style array of strings"); 82} 83ATF_TEST_CASE_BODY(argv_array_init_carray) 84{ 85 { 86 const char* const carray[] = { NULL }; 87 atf::process::argv_array argv(carray); 88 89 ATF_REQUIRE_EQ(argv.size(), 0); 90 } 91 92 { 93 const char* const carray[] = { "arg0", NULL }; 94 atf::process::argv_array argv(carray); 95 96 ATF_REQUIRE_EQ(argv.size(), 1); 97 ATF_REQUIRE(std::strcmp(argv[0], carray[0]) == 0); 98 } 99 100 { 101 const char* const carray[] = { "arg0", "arg1", "arg2", NULL }; 102 atf::process::argv_array argv(carray); 103 104 ATF_REQUIRE_EQ(argv.size(), 3); 105 ATF_REQUIRE(std::strcmp(argv[0], carray[0]) == 0); 106 ATF_REQUIRE(std::strcmp(argv[1], carray[1]) == 0); 107 ATF_REQUIRE(std::strcmp(argv[2], carray[2]) == 0); 108 } 109} 110 111ATF_TEST_CASE(argv_array_init_col); 112ATF_TEST_CASE_HEAD(argv_array_init_col) 113{ 114 set_md_var("descr", "Tests that argv_array is correctly constructed " 115 "from a string collection"); 116} 117ATF_TEST_CASE_BODY(argv_array_init_col) 118{ 119 { 120 std::vector< std::string > col; 121 atf::process::argv_array argv(col); 122 123 ATF_REQUIRE_EQ(argv.size(), 0); 124 } 125 126 { 127 std::vector< std::string > col; 128 col.push_back("arg0"); 129 atf::process::argv_array argv(col); 130 131 ATF_REQUIRE_EQ(argv.size(), 1); 132 ATF_REQUIRE_EQ(argv[0], col[0]); 133 } 134 135 { 136 std::vector< std::string > col; 137 col.push_back("arg0"); 138 col.push_back("arg1"); 139 col.push_back("arg2"); 140 atf::process::argv_array argv(col); 141 142 ATF_REQUIRE_EQ(argv.size(), 3); 143 ATF_REQUIRE_EQ(argv[0], col[0]); 144 ATF_REQUIRE_EQ(argv[1], col[1]); 145 ATF_REQUIRE_EQ(argv[2], col[2]); 146 } 147} 148 149ATF_TEST_CASE(argv_array_init_empty); 150ATF_TEST_CASE_HEAD(argv_array_init_empty) 151{ 152 set_md_var("descr", "Tests that argv_array is correctly constructed " 153 "by the default constructor"); 154} 155ATF_TEST_CASE_BODY(argv_array_init_empty) 156{ 157 atf::process::argv_array argv; 158 159 ATF_REQUIRE_EQ(argv.size(), 0); 160} 161 162ATF_TEST_CASE(argv_array_init_varargs); 163ATF_TEST_CASE_HEAD(argv_array_init_varargs) 164{ 165 set_md_var("descr", "Tests that argv_array is correctly constructed " 166 "from a variable list of arguments"); 167} 168ATF_TEST_CASE_BODY(argv_array_init_varargs) 169{ 170 { 171 atf::process::argv_array argv("arg0", NULL); 172 173 ATF_REQUIRE_EQ(argv.size(), 1); 174 ATF_REQUIRE_EQ(argv[0], std::string("arg0")); 175 } 176 177 { 178 atf::process::argv_array argv("arg0", "arg1", "arg2", NULL); 179 180 ATF_REQUIRE_EQ(argv.size(), 3); 181 ATF_REQUIRE_EQ(argv[0], std::string("arg0")); 182 ATF_REQUIRE_EQ(argv[1], std::string("arg1")); 183 ATF_REQUIRE_EQ(argv[2], std::string("arg2")); 184 } 185} 186 187ATF_TEST_CASE(argv_array_assign); 188ATF_TEST_CASE_HEAD(argv_array_assign) 189{ 190 set_md_var("descr", "Tests that assigning an argv_array works"); 191} 192ATF_TEST_CASE_BODY(argv_array_assign) 193{ 194 using atf::process::argv_array; 195 196 const char* const carray1[] = { "arg1", NULL }; 197 const char* const carray2[] = { "arg1", "arg2", NULL }; 198 199 std::auto_ptr< argv_array > argv1(new argv_array(carray1)); 200 std::auto_ptr< argv_array > argv2(new argv_array(carray2)); 201 202 *argv2 = *argv1; 203 ATF_REQUIRE_EQ(argv2->size(), argv1->size()); 204 ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0); 205 206 ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv()); 207 argv1.release(); 208 { 209 const char* const* eargv2 = argv2->exec_argv(); 210 ATF_REQUIRE(std::strcmp(eargv2[0], carray1[0]) == 0); 211 ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL)); 212 } 213 214 argv2.release(); 215} 216 217ATF_TEST_CASE(argv_array_copy); 218ATF_TEST_CASE_HEAD(argv_array_copy) 219{ 220 set_md_var("descr", "Tests that copying an argv_array constructed from " 221 "a C-style array of strings works"); 222} 223ATF_TEST_CASE_BODY(argv_array_copy) 224{ 225 using atf::process::argv_array; 226 227 const char* const carray[] = { "arg0", NULL }; 228 229 std::auto_ptr< argv_array > argv1(new argv_array(carray)); 230 std::auto_ptr< argv_array > argv2(new argv_array(*argv1)); 231 232 ATF_REQUIRE_EQ(argv2->size(), argv1->size()); 233 ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0); 234 235 ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv()); 236 argv1.release(); 237 { 238 const char* const* eargv2 = argv2->exec_argv(); 239 ATF_REQUIRE(std::strcmp(eargv2[0], carray[0]) == 0); 240 ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL)); 241 } 242 243 argv2.release(); 244} 245 246ATF_TEST_CASE(argv_array_exec_argv); 247ATF_TEST_CASE_HEAD(argv_array_exec_argv) 248{ 249 set_md_var("descr", "Tests that the exec argv provided by an argv_array " 250 "is correct"); 251} 252ATF_TEST_CASE_BODY(argv_array_exec_argv) 253{ 254 using atf::process::argv_array; 255 256 { 257 argv_array argv; 258 const char* const* eargv = argv.exec_argv(); 259 ATF_REQUIRE_EQ(array_size(eargv), 0); 260 ATF_REQUIRE_EQ(eargv[0], static_cast< const char* >(NULL)); 261 } 262 263 { 264 const char* const carray[] = { "arg0", NULL }; 265 argv_array argv(carray); 266 const char* const* eargv = argv.exec_argv(); 267 ATF_REQUIRE_EQ(array_size(eargv), 1); 268 ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0); 269 ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL)); 270 } 271 272 { 273 std::vector< std::string > col; 274 col.push_back("arg0"); 275 argv_array argv(col); 276 const char* const* eargv = argv.exec_argv(); 277 ATF_REQUIRE_EQ(array_size(eargv), 1); 278 ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0); 279 ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL)); 280 } 281} 282 283ATF_TEST_CASE(argv_array_iter); 284ATF_TEST_CASE_HEAD(argv_array_iter) 285{ 286 set_md_var("descr", "Tests that an argv_array can be iterated"); 287} 288ATF_TEST_CASE_BODY(argv_array_iter) 289{ 290 using atf::process::argv_array; 291 292 std::vector< std::string > vector; 293 vector.push_back("arg0"); 294 vector.push_back("arg1"); 295 vector.push_back("arg2"); 296 297 argv_array argv(vector); 298 ATF_REQUIRE_EQ(argv.size(), 3); 299 std::vector< std::string >::size_type pos = 0; 300 for (argv_array::const_iterator iter = argv.begin(); iter != argv.end(); 301 iter++) { 302 ATF_REQUIRE_EQ(*iter, vector[pos]); 303 pos++; 304 } 305} 306 307// ------------------------------------------------------------------------ 308// Tests cases for the free functions. 309// ------------------------------------------------------------------------ 310 311ATF_TEST_CASE(exec_failure); 312ATF_TEST_CASE_HEAD(exec_failure) 313{ 314 set_md_var("descr", "Tests execing a command that reports failure"); 315} 316ATF_TEST_CASE_BODY(exec_failure) 317{ 318 const atf::process::status s = exec_process_helpers(*this, "exit-failure"); 319 ATF_REQUIRE(s.exited()); 320 ATF_REQUIRE_EQ(s.exitstatus(), EXIT_FAILURE); 321} 322 323ATF_TEST_CASE(exec_success); 324ATF_TEST_CASE_HEAD(exec_success) 325{ 326 set_md_var("descr", "Tests execing a command that reports success"); 327} 328ATF_TEST_CASE_BODY(exec_success) 329{ 330 const atf::process::status s = exec_process_helpers(*this, "exit-success"); 331 ATF_REQUIRE(s.exited()); 332 ATF_REQUIRE_EQ(s.exitstatus(), EXIT_SUCCESS); 333} 334 335// ------------------------------------------------------------------------ 336// Main. 337// ------------------------------------------------------------------------ 338 339ATF_INIT_TEST_CASES(tcs) 340{ 341 // Add the test cases for the "argv_array" type. 342 ATF_ADD_TEST_CASE(tcs, argv_array_assign); 343 ATF_ADD_TEST_CASE(tcs, argv_array_copy); 344 ATF_ADD_TEST_CASE(tcs, argv_array_exec_argv); 345 ATF_ADD_TEST_CASE(tcs, argv_array_init_carray); 346 ATF_ADD_TEST_CASE(tcs, argv_array_init_col); 347 ATF_ADD_TEST_CASE(tcs, argv_array_init_empty); 348 ATF_ADD_TEST_CASE(tcs, argv_array_init_varargs); 349 ATF_ADD_TEST_CASE(tcs, argv_array_iter); 350 351 // Add the test cases for the free functions. 352 ATF_ADD_TEST_CASE(tcs, exec_failure); 353 ATF_ADD_TEST_CASE(tcs, exec_success); 354} 355