]>
Commit | Line | Data |
---|---|---|
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/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 | ||
92f5a8d4 | 32 | BOOST_AUTO_TEST_SUITE( bind_stdin ); |
b32b8144 FG |
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 | ||
99 | write_handler(bp::ipstream &is) : is_(is) {} | |
100 | ||
101 | 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 | } | |
92f5a8d4 TL |
259 | |
260 | BOOST_AUTO_TEST_SUITE_END(); |