• 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/process/error.hpp>
15 #include <boost/process/io.hpp>
16 #include <boost/process/child.hpp>
17 #include <boost/process/args.hpp>
18 #include <boost/process/async.hpp>
19 
20 #include <system_error>
21 #include <boost/system/error_code.hpp>
22 #include <boost/filesystem.hpp>
23 
24 #include <boost/asio.hpp>
25 #include <string>
26 #include <cstdlib>
27 #include <iostream>
28 #include <thread>
29 
30 #include <boost/config.hpp>
31 
32 BOOST_AUTO_TEST_SUITE( bind_stdin );
33 
34 #if defined(BOOST_WINDOWS_API)
35 #   include <windows.h>
36 typedef boost::asio::windows::stream_handle pipe_end;
37 #elif defined(BOOST_POSIX_API)
38 #   include <sys/wait.h>
39 #   include <unistd.h>
40 typedef boost::asio::posix::stream_descriptor pipe_end;
41 #endif
42 
43 
44 namespace fs = boost::filesystem;
45 namespace bp = boost::process;
46 
47 BOOST_AUTO_TEST_CASE(sync_io, *boost::unit_test::timeout(10))
48 {
49     std::cout << "sync_io" << std::endl;
50     using boost::unit_test::framework::master_test_suite;
51 
52     bp::opstream os;
53     bp::ipstream is;
54 
55     std::error_code ec;
56 
57     bp::child c(
58         master_test_suite().argv[1],
59         bp::args+={"test", "--prefix", "abc"},
60         bp::std_in <os,
61         bp::std_out>is,
62         ec);
63 
64     BOOST_REQUIRE(!ec);
65 
66 
67 
68     os << "hello" << std::endl;
69 
70     std::string s;
71 
72 
73     is >> s;
74     BOOST_CHECK_EQUAL(s, "abchello");
75     os << 123 << std::endl;
76     is >> s;
77     BOOST_CHECK_EQUAL(s, "abc123");
78     os << 3.1415 << std::endl;
79     is >> s;
80     BOOST_CHECK_EQUAL(s, "abc3.1415");
81 
82     c.terminate();
83     c.wait();
84 
85 
86     std::this_thread::sleep_for(std::chrono::milliseconds(100));
87 
88     int i = -1;
89     is >> i;
90     BOOST_CHECK(is.eof());
91     BOOST_CHECK(!is);
92 }
93 
94 
95 struct write_handler
96 {
97     bp::ipstream &is_;
98 
write_handlerwrite_handler99     write_handler(bp::ipstream &is) : is_(is) {}
100 
operator ()write_handler101     void operator()(const boost::system::error_code &ec, std::size_t size)
102     {
103         BOOST_REQUIRE_EQUAL(6u, size);
104         std::string s;
105         is_ >> s;
106         BOOST_CHECK_EQUAL(s, "abchello");
107     }
108 };
109 
110 BOOST_AUTO_TEST_CASE(async_io, *boost::unit_test::timeout(2))
111 {
112     std::cout << "async_io" << std::endl;
113     using boost::unit_test::framework::master_test_suite;
114 
115     boost::asio::io_context io_context;
116 
117     bp::async_pipe p1(io_context);
118     bp::ipstream is;
119 
120     boost::asio::streambuf sb;
121     std::ostream os(&sb);
122 
123     std::error_code ec;
124     bp::child c(
125         master_test_suite().argv[1],
126         "test", "--prefix-once", "abc",
127         bp::std_in<p1,
128         bp::std_out>is,
129         ec
130     );
131     BOOST_REQUIRE(!ec);
132 
133     os << "hello" << std::endl;
134 
135   //  std::string s = "hello\n";
136     boost::asio::async_write(p1, sb,
137         write_handler(is));
138 
139     io_context.run();
140 
141     c.wait();
142 }
143 
144 BOOST_AUTO_TEST_CASE(nul, *boost::unit_test::timeout(2))
145 {
146     std::cout << "nul" << std::endl;
147 
148     using boost::unit_test::framework::master_test_suite;
149 
150     std::error_code ec;
151     bp::child c(
152         master_test_suite().argv[1],
153         "test", "--is-nul-stdin",
154         bp::std_in<bp::null,
155         ec);
156 
157     BOOST_REQUIRE(!ec);
158 
159     c.wait();
160     int exit_code = c.exit_code();
161 #if defined(BOOST_WINDOWS_API)
162     BOOST_CHECK_EQUAL(EXIT_SUCCESS, exit_code);
163 #elif defined(BOOST_POSIX_API)
164     BOOST_CHECK_EQUAL(EXIT_SUCCESS, exit_code);
165 #endif
166 }
167 
168 
169 BOOST_AUTO_TEST_CASE(file_io, *boost::unit_test::timeout(2))
170 {
171     std::cout << "file_io" << std::endl;
172     using boost::unit_test::framework::master_test_suite;
173 
174 
175     fs::path pth =
176             fs::path(master_test_suite().argv[1]).parent_path() / "std_in_log_file.txt";
177     bp::ipstream is;
178 
179     {
180         boost::filesystem::ofstream fs(pth);
181         fs << 321 << std::endl;
182         fs << 1.2345 << std::endl;
183         fs << "some_string" << std::endl;
184     }
185     std::error_code ec;
186 
187     bp::child c(
188         master_test_suite().argv[1],
189         bp::args+={"test", "--prefix", "abc"},
190         bp::std_in <pth,
191         bp::std_out>is,
192         ec);
193 
194     BOOST_REQUIRE(!ec);
195 
196 
197     std::string s;
198 
199 
200     is >> s;
201     BOOST_CHECK_EQUAL(s, "abc321");
202     is >> s;
203     BOOST_CHECK_EQUAL(s, "abc1.2345");
204     is >> s;
205     BOOST_CHECK_EQUAL(s, "abcsome_string");
206 
207     c.wait();
208     boost::filesystem::remove(pth);
209 }
210 
211 BOOST_AUTO_TEST_CASE(file_io_C, *boost::unit_test::timeout(2))
212 {
213     //tested, since stdin also yields FILE*.
214     std::cout << "file_io_C" << std::endl;
215     using boost::unit_test::framework::master_test_suite;
216 
217 
218     fs::path pth =
219             fs::path(master_test_suite().argv[1]).parent_path() / "std_in_log_file_2.txt";
220     bp::ipstream is;
221 
222     {
223         boost::filesystem::ofstream fs(pth);
224         fs << 321 << std::endl;
225         fs << 1.2345 << std::endl;
226         fs << "some_string" << std::endl;
227     }
228 
229     FILE * f = fopen(pth.string().c_str(), "r+");
230 
231     BOOST_REQUIRE(f != nullptr);
232     std::error_code ec;
233 
234     bp::child c(
235         master_test_suite().argv[1],
236         bp::args+={"test", "--prefix", "abc"},
237         bp::std_in <f,
238         bp::std_out>is,
239         ec);
240 
241     fclose(f);
242 
243     BOOST_REQUIRE(!ec);
244 
245 
246     std::string s;
247 
248 
249     is >> s;
250     BOOST_CHECK_EQUAL(s, "abc321");
251     is >> s;
252     BOOST_CHECK_EQUAL(s, "abc1.2345");
253     is >> s;
254     BOOST_CHECK_EQUAL(s, "abcsome_string");
255 
256     c.wait();
257     boost::filesystem::remove(pth);
258 }
259 
260 BOOST_AUTO_TEST_SUITE_END();