1 // Copyright (c) 2006, 2007 Julio M. Merino Vidal 2 // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling 3 // Copyright (c) 2009 Boris Schaeling 4 // Copyright (c) 2010 Felipe Tanus, Boris Schaeling 5 // Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 10 #define BOOST_TEST_MAIN 11 #define BOOST_TEST_IGNORE_SIGCHLD 12 #include <boost/test/included/unit_test.hpp> 13 14 #include <boost/system/error_code.hpp> 15 16 #include <boost/asio.hpp> 17 #include <boost/algorithm/string/predicate.hpp> 18 19 #include <boost/process/error.hpp> 20 #include <boost/process/io.hpp> 21 #include <boost/process/args.hpp> 22 #include <boost/process/child.hpp> 23 #include <boost/process/group.hpp> 24 #include <system_error> 25 26 #include <string> 27 #include <thread> 28 #include <istream> 29 #include <iostream> 30 #include <cstdlib> 31 32 namespace bp = boost::process; 33 34 BOOST_AUTO_TEST_CASE(group_test, *boost::unit_test::timeout(5)) 35 { 36 std::cout << "group_test" << std::endl; 37 using boost::unit_test::framework::master_test_suite; 38 39 std::error_code ec; 40 bp::group g; 41 42 43 bp::child c( 44 master_test_suite().argv[1], 45 g, 46 ec 47 ); 48 BOOST_CHECK(c.running()); 49 50 BOOST_REQUIRE(!ec); 51 BOOST_REQUIRE(c.in_group()); 52 BOOST_CHECK(c); 53 BOOST_CHECK(c.running()); 54 55 BOOST_REQUIRE_NO_THROW(g.terminate()); 56 std::this_thread::sleep_for(std::chrono::milliseconds(50)); 57 58 BOOST_CHECK(!c.running()); 59 if (c.running()) 60 c.terminate(); 61 62 std::cout << "group_test out" << std::endl; 63 64 } 65 66 BOOST_AUTO_TEST_CASE(attached, *boost::unit_test::timeout(5)) 67 { 68 std::cout << "attached" << std::endl; 69 70 using boost::unit_test::framework::master_test_suite; 71 72 bp::ipstream is; 73 74 bp::group g; 75 76 std::error_code ec; 77 bp::child c( 78 master_test_suite().argv[1], 79 bp::args+={"--launch-attached"}, 80 bp::std_out>is, 81 g, 82 ec 83 ); 84 BOOST_REQUIRE(!ec); 85 BOOST_REQUIRE(c.in_group(ec)); 86 BOOST_CHECK(c); 87 88 89 90 bp::pid_t pid; 91 is >> pid; 92 bp::child sub_c(pid); 93 is >> pid; //invalid pid. 94 95 96 BOOST_REQUIRE(sub_c); 97 std::this_thread::sleep_for(std::chrono::milliseconds(100)); //just to be sure. 98 99 100 #if defined( BOOST_POSIX_API ) 101 ::waitpid(sub_c.id(), nullptr, WNOHANG); 102 BOOST_CHECK(kill(sub_c.id(), 0) == 0); 103 #else 104 BOOST_CHECK(sub_c.running()); 105 #endif 106 107 BOOST_REQUIRE_NO_THROW(g.terminate()); 108 109 BOOST_CHECK(sub_c); 110 std::this_thread::sleep_for(std::chrono::milliseconds(100)); //just to be sure. 111 112 BOOST_CHECK(!c.running()); 113 114 #if defined( BOOST_POSIX_API ) 115 errno = 0; 116 ::waitpid(sub_c.id(), nullptr, WNOHANG); 117 bool still_runs = (kill(sub_c.id(), 0) == 0) && (errno != ECHILD) && (errno != ESRCH); 118 #else 119 bool still_runs = sub_c.running(); 120 #endif 121 BOOST_CHECK_MESSAGE(!still_runs, boost::process::detail::get_last_error().message()); 122 123 if (still_runs) 124 sub_c.terminate(); 125 BOOST_CHECK(!c.running()); 126 if (c.running()) 127 c.terminate(); 128 129 std::cout << "attached out" << std::endl; 130 131 } 132 133 134 135 BOOST_AUTO_TEST_CASE(detached, *boost::unit_test::timeout(5)) 136 { 137 std::cerr << "detached" << std::endl; 138 139 using boost::unit_test::framework::master_test_suite; 140 141 bp::ipstream is; 142 143 bp::group g; 144 145 146 std::error_code ec; 147 bp::child c( 148 master_test_suite().argv[1], 149 bp::args+={"--launch-detached"}, 150 bp::std_out>is, 151 g, 152 ec 153 ); 154 155 BOOST_REQUIRE(!ec); 156 BOOST_CHECK(c); 157 158 bp::pid_t pid; 159 is >> pid; 160 is >> pid; 161 bp::child sub_c(pid); 162 163 std::this_thread::sleep_for(std::chrono::milliseconds(50)); //just to be sure. 164 165 #if defined( BOOST_POSIX_API ) 166 BOOST_CHECK(kill(sub_c.id(), 0) == 0); 167 #else 168 BOOST_CHECK(sub_c.running()); 169 #endif 170 171 BOOST_REQUIRE_NO_THROW(g.terminate()); 172 173 BOOST_CHECK(sub_c); 174 std::this_thread::sleep_for(std::chrono::milliseconds(50)); //just to be sure. 175 176 #if defined( BOOST_POSIX_API ) 177 bool still_runs = kill(sub_c.id(), 0) == 0; 178 #else 179 bool still_runs = sub_c.running(); 180 #endif 181 182 BOOST_CHECK(still_runs); 183 if (still_runs) 184 sub_c.terminate(); 185 186 BOOST_CHECK(!c.running()); 187 if (c.running()) 188 c.terminate(); 189 190 std::cerr << "detached out" << std::endl; 191 } 192