• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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