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 45 static 46 std::size_t 47 array_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 57 static 58 atf::process::status 59 exec_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 77 ATF_TEST_CASE(argv_array_init_carray); 78 ATF_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 } 83 ATF_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 111 ATF_TEST_CASE(argv_array_init_col); 112 ATF_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 } 117 ATF_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 149 ATF_TEST_CASE(argv_array_init_empty); 150 ATF_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 } 155 ATF_TEST_CASE_BODY(argv_array_init_empty) 156 { 157 atf::process::argv_array argv; 158 159 ATF_REQUIRE_EQ(argv.size(), 0); 160 } 161 162 ATF_TEST_CASE(argv_array_init_varargs); 163 ATF_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 } 168 ATF_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 187 ATF_TEST_CASE(argv_array_assign); 188 ATF_TEST_CASE_HEAD(argv_array_assign) 189 { 190 set_md_var("descr", "Tests that assigning an argv_array works"); 191 } 192 ATF_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 argv_array argv1 = argv_array(carray1); 200 argv_array argv2 = 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 { 208 const char* const* eargv2 = argv2.exec_argv(); 209 ATF_REQUIRE(std::strcmp(eargv2[0], carray1[0]) == 0); 210 ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL)); 211 } 212 } 213 214 ATF_TEST_CASE(argv_array_copy); 215 ATF_TEST_CASE_HEAD(argv_array_copy) 216 { 217 set_md_var("descr", "Tests that copying an argv_array constructed from " 218 "a C-style array of strings works"); 219 } 220 ATF_TEST_CASE_BODY(argv_array_copy) 221 { 222 using atf::process::argv_array; 223 224 const char* const carray[] = { "arg0", NULL }; 225 226 argv_array argv1 = argv_array(carray); 227 argv_array argv2 = argv1; 228 229 ATF_REQUIRE_EQ(argv2.size(), argv1.size()); 230 ATF_REQUIRE(std::strcmp(argv2[0], argv1[0]) == 0); 231 232 ATF_REQUIRE(argv2.exec_argv() != argv1.exec_argv()); 233 { 234 const char* const* eargv2 = argv2.exec_argv(); 235 ATF_REQUIRE(std::strcmp(eargv2[0], carray[0]) == 0); 236 ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL)); 237 } 238 } 239 240 ATF_TEST_CASE(argv_array_exec_argv); 241 ATF_TEST_CASE_HEAD(argv_array_exec_argv) 242 { 243 set_md_var("descr", "Tests that the exec argv provided by an argv_array " 244 "is correct"); 245 } 246 ATF_TEST_CASE_BODY(argv_array_exec_argv) 247 { 248 using atf::process::argv_array; 249 250 { 251 argv_array argv; 252 const char* const* eargv = argv.exec_argv(); 253 ATF_REQUIRE_EQ(array_size(eargv), 0); 254 ATF_REQUIRE_EQ(eargv[0], static_cast< const char* >(NULL)); 255 } 256 257 { 258 const char* const carray[] = { "arg0", NULL }; 259 argv_array argv(carray); 260 const char* const* eargv = argv.exec_argv(); 261 ATF_REQUIRE_EQ(array_size(eargv), 1); 262 ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0); 263 ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL)); 264 } 265 266 { 267 std::vector< std::string > col; 268 col.push_back("arg0"); 269 argv_array argv(col); 270 const char* const* eargv = argv.exec_argv(); 271 ATF_REQUIRE_EQ(array_size(eargv), 1); 272 ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0); 273 ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL)); 274 } 275 } 276 277 ATF_TEST_CASE(argv_array_iter); 278 ATF_TEST_CASE_HEAD(argv_array_iter) 279 { 280 set_md_var("descr", "Tests that an argv_array can be iterated"); 281 } 282 ATF_TEST_CASE_BODY(argv_array_iter) 283 { 284 using atf::process::argv_array; 285 286 std::vector< std::string > vector; 287 vector.push_back("arg0"); 288 vector.push_back("arg1"); 289 vector.push_back("arg2"); 290 291 argv_array argv(vector); 292 ATF_REQUIRE_EQ(argv.size(), 3); 293 std::vector< std::string >::size_type pos = 0; 294 for (argv_array::const_iterator iter = argv.begin(); iter != argv.end(); 295 iter++) { 296 ATF_REQUIRE_EQ(*iter, vector[pos]); 297 pos++; 298 } 299 } 300 301 // ------------------------------------------------------------------------ 302 // Tests cases for the free functions. 303 // ------------------------------------------------------------------------ 304 305 ATF_TEST_CASE(exec_failure); 306 ATF_TEST_CASE_HEAD(exec_failure) 307 { 308 set_md_var("descr", "Tests execing a command that reports failure"); 309 } 310 ATF_TEST_CASE_BODY(exec_failure) 311 { 312 const atf::process::status s = exec_process_helpers(*this, "exit-failure"); 313 ATF_REQUIRE(s.exited()); 314 ATF_REQUIRE_EQ(s.exitstatus(), EXIT_FAILURE); 315 } 316 317 ATF_TEST_CASE(exec_success); 318 ATF_TEST_CASE_HEAD(exec_success) 319 { 320 set_md_var("descr", "Tests execing a command that reports success"); 321 } 322 ATF_TEST_CASE_BODY(exec_success) 323 { 324 const atf::process::status s = exec_process_helpers(*this, "exit-success"); 325 ATF_REQUIRE(s.exited()); 326 ATF_REQUIRE_EQ(s.exitstatus(), EXIT_SUCCESS); 327 } 328 329 // ------------------------------------------------------------------------ 330 // Main. 331 // ------------------------------------------------------------------------ 332 333 ATF_INIT_TEST_CASES(tcs) 334 { 335 // Add the test cases for the "argv_array" type. 336 ATF_ADD_TEST_CASE(tcs, argv_array_assign); 337 ATF_ADD_TEST_CASE(tcs, argv_array_copy); 338 ATF_ADD_TEST_CASE(tcs, argv_array_exec_argv); 339 ATF_ADD_TEST_CASE(tcs, argv_array_init_carray); 340 ATF_ADD_TEST_CASE(tcs, argv_array_init_col); 341 ATF_ADD_TEST_CASE(tcs, argv_array_init_empty); 342 ATF_ADD_TEST_CASE(tcs, argv_array_init_varargs); 343 ATF_ADD_TEST_CASE(tcs, argv_array_iter); 344 345 // Add the test cases for the free functions. 346 ATF_ADD_TEST_CASE(tcs, exec_failure); 347 ATF_ADD_TEST_CASE(tcs, exec_success); 348 } 349