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/spawn.hpp> 23 #include <boost/process/async_pipe.hpp> 24 #include <boost/process/async.hpp> 25 #include <system_error> 26 27 #include <boost/filesystem.hpp> 28 29 #include <string> 30 #include <istream> 31 #include <cstdlib> 32 #if defined(BOOST_WINDOWS_API) 33 # include <windows.h> 34 typedef boost::asio::windows::stream_handle pipe_end; 35 #elif defined(BOOST_POSIX_API) 36 # include <sys/wait.h> 37 # include <unistd.h> 38 typedef boost::asio::posix::stream_descriptor pipe_end; 39 #endif 40 41 namespace fs = boost::filesystem; 42 namespace bp = boost::process; 43 44 BOOST_AUTO_TEST_CASE(sync_spawn, *boost::unit_test::timeout(5)) 45 { 46 using boost::unit_test::framework::master_test_suite; 47 48 bp::ipstream is; 49 std::error_code ec; 50 51 bp::spawn( 52 master_test_suite().argv[1], 53 bp::args+={"test", "--echo-stdout", "hello"}, 54 bp::std_out > is, 55 ec 56 ); 57 58 BOOST_CHECK(!ec); 59 60 61 std::string s; 62 63 BOOST_TEST_CHECKPOINT("Starting read"); 64 is >> s; 65 BOOST_TEST_CHECKPOINT("Finished read"); 66 67 BOOST_CHECK_EQUAL(s, "hello"); 68 } 69 70 71 struct read_handler 72 { 73 boost::asio::streambuf &buffer_; 74 read_handlerread_handler75 read_handler(boost::asio::streambuf &buffer) : buffer_(buffer) {} 76 operator ()read_handler77 void operator()(const boost::system::error_code &ec, std::size_t size) 78 { 79 std::istream is(&buffer_); 80 std::string line; 81 std::getline(is, line); 82 BOOST_CHECK(boost::algorithm::starts_with(line, "abc")); 83 } 84 }; 85 86 BOOST_AUTO_TEST_CASE(async_spawn, *boost::unit_test::timeout(2)) 87 { 88 using boost::unit_test::framework::master_test_suite; 89 90 boost::asio::io_context io_context; 91 bp::async_pipe p(io_context); 92 93 std::error_code ec; 94 bp::spawn( 95 master_test_suite().argv[1], 96 "test", "--echo-stdout", "abc", 97 bp::std_out > p, 98 ec 99 ); 100 BOOST_REQUIRE(!ec); 101 102 boost::asio::streambuf buffer; 103 boost::asio::async_read_until(p, buffer, '\n', 104 read_handler(buffer)); 105 106 io_context.run(); 107 } 108 109 110