]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/process/test/async.cpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / libs / process / test / async.cpp
CommitLineData
b32b8144
FG
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/process/error.hpp>
15#include <boost/process/async.hpp>
16#include <boost/process/io.hpp>
17#include <boost/process/child.hpp>
18
19#include <boost/thread.hpp>
20#include <future>
21
22#include <boost/system/error_code.hpp>
23
24#include <boost/algorithm/string/predicate.hpp>
25
26
27using namespace std;
28
29namespace bp = boost::process;
30
31BOOST_AUTO_TEST_CASE(async_wait, *boost::unit_test::timeout(2))
32{
33 using boost::unit_test::framework::master_test_suite;
34 using namespace boost::asio;
35
36 boost::asio::io_context io_context;
37
11fdf7f2
TL
38 std::error_code ec;
39
40 bool exit_called_for_c1 = false;
41 int exit_code_c1 = 0;
42 bp::child c1(
43 master_test_suite().argv[1],
44 "test", "--exit-code", "123",
45 ec,
46 io_context,
47 bp::on_exit([&](int exit, const std::error_code& ec_in)
48 {
49 BOOST_CHECK(!exit_called_for_c1);
50 exit_code_c1 = exit; exit_called_for_c1=true;
51 BOOST_CHECK(!ec_in);
52 })
53 );
54 BOOST_REQUIRE(!ec);
55
56 bool exit_called_for_c2 = false;
57 int exit_code_c2 = 0;
58 bp::child c2(
59 master_test_suite().argv[1],
60 "test", "--exit-code", "21",
61 ec,
62 io_context,
63 bp::on_exit([&](int exit, const std::error_code& ec_in)
64 {
65 BOOST_CHECK(!exit_called_for_c2);
66 exit_code_c2 = exit; exit_called_for_c2=true;
67 BOOST_CHECK(!ec_in);
68 })
69 );
70 BOOST_REQUIRE(!ec);
71
72 io_context.run();
73
74 BOOST_CHECK(exit_called_for_c1);
75 BOOST_CHECK_EQUAL(exit_code_c1, 123);
76 BOOST_CHECK_EQUAL(c1.exit_code(), 123);
77
78 BOOST_CHECK(exit_called_for_c2);
79 BOOST_CHECK_EQUAL(exit_code_c2, 21);
80 BOOST_CHECK_EQUAL(c2.exit_code(), 21);
81}
82
83BOOST_AUTO_TEST_CASE(async_wait_sync_wait, *boost::unit_test::timeout(3))
84{
85 using boost::unit_test::framework::master_test_suite;
86 using namespace boost::asio;
87
88 boost::asio::io_context io_context;
89
b32b8144
FG
90 bool exit_called = false;
91 int exit_code = 0;
92 std::error_code ec;
11fdf7f2 93 bp::child c1(
b32b8144 94 master_test_suite().argv[1],
11fdf7f2
TL
95 "test", "--exit-code", "1",
96 ec
97 );
98 BOOST_REQUIRE(!ec);
99
100 bp::child c2(
101 master_test_suite().argv[1],
102 "test", "--exit-code", "2", "--wait", "1",
b32b8144
FG
103 ec,
104 io_context,
105 bp::on_exit([&](int exit, const std::error_code& ec_in)
106 {
107 exit_code = exit; exit_called=true;
108 BOOST_CHECK(!ec_in);
109 })
110 );
11fdf7f2
TL
111 BOOST_REQUIRE(!ec);
112
113 io_context.run();
114 // Regression test for #143: make sure the async SIGCHLD handler on POSIX does not reap the
115 // child c1 is watching (this will error if so)
116 c1.wait(ec);
117 BOOST_REQUIRE(!ec);
118
119 BOOST_CHECK(exit_called);
120 BOOST_CHECK_EQUAL(exit_code, 2);
121 BOOST_CHECK_EQUAL(c2.exit_code(), 2);
122}
123
124BOOST_AUTO_TEST_CASE(async_wait_different_contexts, *boost::unit_test::timeout(3))
125{
126 using boost::unit_test::framework::master_test_suite;
127 using namespace boost::asio;
128
129 boost::asio::io_context io_context1;
130 boost::asio::io_context io_context2;
131
132 std::error_code ec;
133
134 bool exit_called_for_c1 = false;
135 int exit_code_c1 = 0;
136 bp::child c1(
137 master_test_suite().argv[1],
138 "test", "--exit-code", "1",
139 ec,
140 io_context1,
141 bp::on_exit([&](int exit, const std::error_code& ec_in)
142 {
143 BOOST_CHECK(!exit_called_for_c1);
144 exit_code_c1 = exit; exit_called_for_c1=true;
145 BOOST_CHECK(!ec_in);
146 })
147 );
148 BOOST_REQUIRE(!ec);
149
150 bool exit_called_for_c2 = false;
151 int exit_code_c2 = 0;
152 bp::child c2(
153 master_test_suite().argv[1],
154 "test", "--exit-code", "2", "--wait", "1",
155 ec,
156 io_context2,
157 bp::on_exit([&](int exit, const std::error_code& ec_in)
158 {
159 BOOST_CHECK(!exit_called_for_c2);
160 exit_code_c2 = exit; exit_called_for_c2=true;
161 BOOST_CHECK(!ec_in);
162 })
163 );
164 BOOST_REQUIRE(!ec);
b32b8144 165
11fdf7f2
TL
166 // Regression test for #143: make sure each io_context handles its own children
167 io_context2.run();
168 io_context1.run();
169 c1.wait(ec);
b32b8144 170 BOOST_REQUIRE(!ec);
11fdf7f2
TL
171
172 BOOST_CHECK(exit_called_for_c1);
173 BOOST_CHECK_EQUAL(exit_code_c1, 1);
174 BOOST_CHECK_EQUAL(c1.exit_code(), 1);
175 BOOST_CHECK(exit_called_for_c2);
176 BOOST_CHECK_EQUAL(exit_code_c2, 2);
177 BOOST_CHECK_EQUAL(c2.exit_code(), 2);
178}
179
180BOOST_AUTO_TEST_CASE(async_wait_abort, *boost::unit_test::timeout(2))
181{
182 using boost::unit_test::framework::master_test_suite;
183 using namespace boost::asio;
184
185 boost::asio::io_context io_context;
186
187 std::error_code ec;
188
189 bool exit_called = false;
190 int exit_code = 0;
191 bp::child c(
192 master_test_suite().argv[1],
193 "test", "--abort",
194 ec,
195 io_context,
196 bp::on_exit([&](int exit, const std::error_code& ec_in)
197 {
198 BOOST_CHECK(!exit_called);
199 exit_code = exit; exit_called=true;
200 BOOST_TEST_MESSAGE(ec_in.message());
201 BOOST_CHECK(!ec_in);
202 })
203 );
204 BOOST_REQUIRE(!ec);
205
b32b8144 206 io_context.run();
11fdf7f2 207
b32b8144 208 BOOST_CHECK(exit_called);
11fdf7f2
TL
209 BOOST_CHECK(exit_code != 0);
210 BOOST_CHECK_EQUAL(c.exit_code(), exit_code);
b32b8144
FG
211}
212
213
214BOOST_AUTO_TEST_CASE(async_future, *boost::unit_test::timeout(2))
215{
216 using boost::unit_test::framework::master_test_suite;
217 using namespace boost::asio;
218
219 boost::asio::io_context io_context;
220
221 std::error_code ec;
222 std::future<int> fut;
223 bp::child c(
224 master_test_suite().argv[1],
225 "test", "--exit-code", "42",
226 ec,
227 io_context,
228 bp::on_exit=fut
229 );
230
231 BOOST_REQUIRE(!ec);
232 io_context.run();
233 BOOST_REQUIRE(fut.valid());
234 BOOST_CHECK_EQUAL(fut.get(), 42);
235}
236
237
238BOOST_AUTO_TEST_CASE(async_out_stream, *boost::unit_test::timeout(2))
239{
240 using boost::unit_test::framework::master_test_suite;
241
242 boost::asio::io_context io_context;
243
244
245 std::error_code ec;
246
247 boost::asio::streambuf buf;
248
249 bp::child c(master_test_suite().argv[1],
250 "test", "--echo-stdout", "abc",
251 bp::std_out > buf,
252 io_context,
253 ec);
254 BOOST_REQUIRE(!ec);
255
256
257 io_context.run();
258 std::istream istr(&buf);
259
260 std::string line;
261 std::getline(istr, line);
262 BOOST_REQUIRE_GE(line.size(), 3);
263 BOOST_CHECK(boost::algorithm::starts_with(line, "abc"));
264 c.wait();
265}
266
267
268
269BOOST_AUTO_TEST_CASE(async_in_stream, *boost::unit_test::timeout(2))
270{
271
272 using boost::unit_test::framework::master_test_suite;
273
274 boost::asio::io_context io_context;
275
276
277 std::error_code ec;
278
279 boost::asio::streambuf buf;
280 boost::asio::streambuf in_buf;
281
282
283 std::ostream ostr(&in_buf);
284 ostr << "-string" << endl ;
285
286 bp::child c(
287 master_test_suite().argv[1],
288 "test", "--prefix-once", "test",
289 bp::std_in < in_buf,
290 bp::std_out > buf,
291 io_context,
292 ec
293 );
294 BOOST_REQUIRE(!ec);
295
296
297 io_context.run();
298 std::istream istr(&buf);
299
300 std::string line;
301 std::getline(istr, line);
302
303 std::string val = "test-string";
304 BOOST_REQUIRE_GE(line.size(), val.size());
305 if (line >= val)
306 BOOST_CHECK(boost::algorithm::starts_with(line, val));
307
308
309 c.wait();
310}
311
312
313BOOST_AUTO_TEST_CASE(async_error, *boost::unit_test::timeout(2))
314{
315 using boost::unit_test::framework::master_test_suite;
316 using namespace boost::asio;
317
318 boost::asio::io_context io_context;
319
320 bool exit_called = false;
321 std::error_code ec;
322 bp::child c(
323 "doesn't exist",
324 ec,
325 io_context,
326 bp::on_exit([&](int exit, const std::error_code& ec_in)
327 {
328 exit_called=true;
329 })
330 );
331
332 BOOST_REQUIRE(ec);
333 io_context.run();
334 BOOST_CHECK(!exit_called);
335}
336