1 // Copyright (c) 2016 Klemens D. Morgenstern 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 7 #define BOOST_TEST_MAIN 8 9 #include <boost/test/included/unit_test.hpp> 10 #include <iostream> 11 #include <thread> 12 13 #include <boost/process/pipe.hpp> 14 #include <boost/process/environment.hpp> 15 16 using namespace std; 17 namespace bp = boost::process; 18 19 BOOST_AUTO_TEST_SUITE( pipe_tests ); 20 21 22 BOOST_AUTO_TEST_CASE(plain, *boost::unit_test::timeout(2)) 23 { 24 bp::pipe pipe; 25 26 std::string in = "test"; 27 pipe.write(in.c_str(), in.size()); 28 29 std::string out; 30 out.resize(4); 31 pipe.read(&out.front(), out.size()); 32 33 BOOST_CHECK_EQUAL(out, in); 34 } 35 36 BOOST_AUTO_TEST_CASE(named, *boost::unit_test::timeout(2)) 37 { 38 39 #if defined( BOOST_WINDOWS_API ) 40 bp::pipe pipe("\\\\.\\pipe\\pipe_name"); 41 #elif defined( BOOST_POSIX_API ) 42 const auto home_path = boost::this_process::environment()["HOME"].to_string(); 43 bp::pipe pipe(home_path + "/.boost_process_test_pipe"); 44 #endif 45 46 std::string in = "xyz"; 47 pipe.write(in.c_str(), in.size()); 48 49 50 std::string out; 51 out.resize(3); 52 pipe.read(&out.front(), out.size()); 53 54 55 BOOST_CHECK_EQUAL(out, in); 56 } 57 58 BOOST_AUTO_TEST_CASE(copy_pipe, *boost::unit_test::timeout(2)) 59 { 60 bp::pipe pipe; 61 62 std::string in = "test"; 63 pipe.write(in.c_str(), in.size()); 64 65 std::string out; 66 out.resize(4); 67 auto p2 = pipe; 68 p2.read(&out.front(), out.size()); 69 70 BOOST_CHECK_EQUAL(out, in); 71 } 72 73 BOOST_AUTO_TEST_CASE(move_pipe, *boost::unit_test::timeout(2)) 74 { 75 bp::pipe pipe; 76 77 std::string in = "test"; 78 pipe.write(in.c_str(), in.size()); 79 80 std::string out; 81 out.resize(4); 82 auto p2 = std::move(pipe); 83 p2.read(&out.front(), out.size()); 84 85 BOOST_CHECK_EQUAL(out, in); 86 } 87 88 BOOST_AUTO_TEST_CASE(stream, *boost::unit_test::timeout(2)) 89 { 90 91 bp::pipe pipe; 92 93 bp::pstream os(pipe); 94 bp::ipstream is(pipe); 95 96 int i = 42, j = 0; 97 98 os << i << std::endl; 99 os << std::endl; 100 is >> j; 101 102 BOOST_CHECK_EQUAL(i, j); 103 } 104 105 BOOST_AUTO_TEST_CASE(stream_move, *boost::unit_test::timeout(2)) 106 { 107 108 bp::pipe pipe; 109 110 bp::pstream os(pipe); 111 bp::ipstream is(pipe); 112 113 int i = 42, j = 0, k = 0; 114 115 os << i << std::endl; 116 os << std::endl; 117 is >> j; 118 119 BOOST_CHECK_EQUAL(i, j); 120 121 bp::pstream os2 = std::move(os); 122 bp::ipstream is2 = std::move(is); 123 os2 << i << std::endl; 124 os2 << std::endl; 125 is2 >> k; 126 127 BOOST_CHECK_EQUAL(i, k); 128 } 129 130 BOOST_AUTO_TEST_CASE(ostream_move, *boost::unit_test::timeout(2)) 131 { 132 133 bp::pipe pipe; 134 135 bp::opstream os(pipe); 136 bp::ipstream is(pipe); 137 138 int i = 42, j = 0, k = 0; 139 140 os << i << std::endl; 141 os << std::endl; 142 is >> j; 143 144 BOOST_CHECK_EQUAL(i, j); 145 146 bp::opstream os2 = std::move(os); 147 bp::ipstream is2 = std::move(is); 148 os2 << i << std::endl; 149 os2 << std::endl; 150 is2 >> k; 151 152 BOOST_CHECK_EQUAL(i, k); 153 } 154 155 BOOST_AUTO_TEST_CASE(stream_move_assignment, *boost::unit_test::timeout(2)) 156 { 157 158 bp::pipe pipe; 159 160 bp::pstream os(pipe); 161 bp::ipstream is(pipe); 162 163 int i = 42, j = 0, k = 0; 164 165 os << i << std::endl; 166 os << std::endl; 167 is >> j; 168 169 BOOST_CHECK_EQUAL(i, j); 170 171 bp::pstream os2; 172 os2 = std::move(os); 173 bp::ipstream is2; 174 is2 = std::move(is); 175 os2 << i << std::endl; 176 os2 << std::endl; 177 is2 >> k; 178 179 BOOST_CHECK_EQUAL(i, k); 180 } 181 182 BOOST_AUTO_TEST_CASE(ostream_move_assignment, *boost::unit_test::timeout(2)) 183 { 184 185 bp::pipe pipe; 186 187 bp::opstream os(pipe); 188 bp::ipstream is(pipe); 189 190 int i = 42, j = 0, k = 0; 191 192 os << i << std::endl; 193 os << std::endl; 194 is >> j; 195 196 BOOST_CHECK_EQUAL(i, j); 197 198 bp::opstream os2; 199 os2 = std::move(os); 200 bp::ipstream is2; 201 is2 = std::move(is); 202 os2 << i << std::endl; 203 os2 << std::endl; 204 is2 >> k; 205 206 BOOST_CHECK_EQUAL(i, k); 207 } 208 209 BOOST_AUTO_TEST_CASE(stream_line, *boost::unit_test::timeout(2)) 210 { 211 212 bp::pstream os; 213 214 std::string s = "My Test String"; 215 216 std::string out; 217 218 os << s << std::endl; 219 220 std::getline(os, out); 221 222 auto size = (out.size() < s.size()) ? out.size() : s.size(); 223 224 225 BOOST_CHECK_EQUAL_COLLECTIONS( 226 s.begin(), s. begin() + size, 227 out.begin(), out.begin() + size 228 ); 229 } 230 231 232 BOOST_AUTO_TEST_CASE(large_data, *boost::unit_test::timeout(20)) 233 { 234 bp::pipe pipe; 235 236 bp::pipebuf is_buf(pipe); 237 bp::pipebuf os_buf(std::move(pipe)); 238 239 std::istream is(&is_buf); 240 std::ostream os(&os_buf); 241 242 std::string in(1000000, '0'); 243 std::string out; 244 245 int cnt = 0; 246 for (auto & c: in) 247 c = (cnt++ % 26) + 'A'; 248 __anon4c22c1ef0102null249 std::thread th([&]{os << in << std::endl;}); 250 251 is >> out; 252 BOOST_REQUIRE_EQUAL_COLLECTIONS(out.begin(), out.end(), in.begin(), in.end()); 253 th.join(); 254 } 255 256 BOOST_AUTO_TEST_CASE(closed, *boost::unit_test::timeout(2)) 257 { 258 bp::opstream os; 259 bp::ipstream is; 260 261 os.pipe().close(); 262 is.pipe().close(); 263 264 int i; 265 266 BOOST_CHECK(!(os << 42 << endl)); 267 BOOST_CHECK(!(is >> i)); 268 } 269 270 271 BOOST_AUTO_TEST_CASE(coverage, *boost::unit_test::timeout(5)) 272 { 273 //more of a syntax check, since template. 274 { 275 bp::pipe p1; 276 bp::ipstream is1(p1); 277 bp::ipstream is2(std::move(p1)); 278 279 is2.pipe(is1.pipe()); 280 281 bp::pipe p2_; 282 bp::pipe p2 = p2_; 283 BOOST_REQUIRE_NO_THROW(p2_ == p2); 284 BOOST_CHECK(p2_ == p2); 285 286 bp::opstream os1(p2); 287 bp::opstream os2(std::move(p2)); 288 289 os2.pipe(os1.pipe()); 290 291 bp::pipe p3; 292 is1 = p3; 293 is2 = std::move(p3); 294 295 bp::pipe p4_; 296 bp::pipe p4 = std::move(p4_); 297 298 bp::pipe p5; 299 BOOST_REQUIRE_NO_THROW(p4_ != p4); 300 BOOST_CHECK(p4_ != p4); 301 302 BOOST_REQUIRE_NO_THROW(p5 != p4); 303 BOOST_CHECK(p4 != p5); 304 305 is1 = p4; 306 is2 = std::move(p4); 307 } 308 { 309 bp::wpipe p; 310 bp::wpstream ws1(p); 311 bp::wpstream ws2(std::move(p)); 312 313 ws2.pipe(std::move(ws1.pipe())); 314 315 bp::wpipe p2; 316 317 ws1 = p2; 318 ws2 = std::move(p2); 319 320 const bp::wpstream & ws2c = ws2; 321 ws1.pipe(ws2c.pipe()); 322 } 323 324 { 325 bp::wpipe p; 326 bp::wpipebuf ws1(p); 327 bp::wpipebuf ws2(std::move(p)); 328 329 ws2.pipe(std::move(ws1.pipe())); 330 331 bp::wpipe p2; 332 333 ws1 = p2; 334 ws2 = std::move(p2); 335 336 const bp::wpipebuf & ws2c = ws2; 337 ws1.pipe(ws2c.pipe()); 338 339 } 340 } 341 342 343 BOOST_AUTO_TEST_CASE(stream_close, *boost::unit_test::timeout(5)) 344 { 345 bp::pipe p; 346 int i = 1234, j = 0; 347 bp::opstream op{p}; 348 bp::ipstream ip{p}; 349 p.close(); 350 351 op << i << " "; 352 op.close(); 353 354 ip >> j; 355 356 BOOST_CHECK_EQUAL(i, j); 357 } 358 359 BOOST_AUTO_TEST_CASE(stream_close_scope, *boost::unit_test::timeout(5)) 360 { 361 bp::pipe p; 362 int i = 1234, j = 0; 363 bp::ipstream ip; 364 365 { 366 bp::opstream op{ip.pipe()}; 367 op << i << " "; 368 } 369 ip >> j; 370 371 BOOST_CHECK_EQUAL(i, j); 372 } 373 374 375 BOOST_AUTO_TEST_SUITE_END(); 376