pipe.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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. #define BOOST_TEST_MAIN
  6. #include <boost/test/included/unit_test.hpp>
  7. #include <iostream>
  8. #include <thread>
  9. #include <boost/process/pipe.hpp>
  10. #include <boost/process/environment.hpp>
  11. using namespace std;
  12. namespace bp = boost::process;
  13. BOOST_AUTO_TEST_SUITE( pipe_tests );
  14. BOOST_AUTO_TEST_CASE(plain, *boost::unit_test::timeout(2))
  15. {
  16. bp::pipe pipe;
  17. std::string in = "test";
  18. pipe.write(in.c_str(), in.size());
  19. std::string out;
  20. out.resize(4);
  21. pipe.read(&out.front(), out.size());
  22. BOOST_CHECK_EQUAL(out, in);
  23. }
  24. BOOST_AUTO_TEST_CASE(named, *boost::unit_test::timeout(2))
  25. {
  26. #if defined( BOOST_WINDOWS_API )
  27. bp::pipe pipe("\\\\.\\pipe\\pipe_name");
  28. #elif defined( BOOST_POSIX_API )
  29. const auto home_path = boost::this_process::environment()["HOME"].to_string();
  30. bp::pipe pipe(home_path + "/.boost_process_test_pipe");
  31. #endif
  32. std::string in = "xyz";
  33. pipe.write(in.c_str(), in.size());
  34. std::string out;
  35. out.resize(3);
  36. pipe.read(&out.front(), out.size());
  37. BOOST_CHECK_EQUAL(out, in);
  38. }
  39. BOOST_AUTO_TEST_CASE(copy_pipe, *boost::unit_test::timeout(2))
  40. {
  41. bp::pipe pipe;
  42. std::string in = "test";
  43. pipe.write(in.c_str(), in.size());
  44. std::string out;
  45. out.resize(4);
  46. auto p2 = pipe;
  47. p2.read(&out.front(), out.size());
  48. BOOST_CHECK_EQUAL(out, in);
  49. }
  50. BOOST_AUTO_TEST_CASE(move_pipe, *boost::unit_test::timeout(2))
  51. {
  52. bp::pipe pipe;
  53. std::string in = "test";
  54. pipe.write(in.c_str(), in.size());
  55. std::string out;
  56. out.resize(4);
  57. auto p2 = std::move(pipe);
  58. p2.read(&out.front(), out.size());
  59. BOOST_CHECK_EQUAL(out, in);
  60. }
  61. BOOST_AUTO_TEST_CASE(stream, *boost::unit_test::timeout(2))
  62. {
  63. bp::pipe pipe;
  64. bp::pstream os(pipe);
  65. bp::ipstream is(pipe);
  66. int i = 42, j = 0;
  67. os << i << std::endl;
  68. os << std::endl;
  69. is >> j;
  70. BOOST_CHECK_EQUAL(i, j);
  71. }
  72. BOOST_AUTO_TEST_CASE(stream_line, *boost::unit_test::timeout(2))
  73. {
  74. bp::pstream os;
  75. std::string s = "My Test String";
  76. std::string out;
  77. os << s << std::endl;
  78. std::getline(os, out);
  79. auto size = (out.size() < s.size()) ? out.size() : s.size();
  80. BOOST_CHECK_EQUAL_COLLECTIONS(
  81. s.begin(), s. begin() + size,
  82. out.begin(), out.begin() + size
  83. );
  84. }
  85. BOOST_AUTO_TEST_CASE(large_data, *boost::unit_test::timeout(20))
  86. {
  87. bp::pipe pipe;
  88. bp::pipebuf is_buf(pipe);
  89. bp::pipebuf os_buf(std::move(pipe));
  90. std::istream is(&is_buf);
  91. std::ostream os(&os_buf);
  92. std::string in(1000000, '0');
  93. std::string out;
  94. int cnt = 0;
  95. for (auto & c: in)
  96. c = (cnt++ % 26) + 'A';
  97. std::thread th([&]{os << in << std::endl;});
  98. is >> out;
  99. BOOST_REQUIRE_EQUAL_COLLECTIONS(out.begin(), out.end(), in.begin(), in.end());
  100. th.join();
  101. }
  102. BOOST_AUTO_TEST_CASE(closed, *boost::unit_test::timeout(2))
  103. {
  104. bp::opstream os;
  105. bp::ipstream is;
  106. os.pipe().close();
  107. is.pipe().close();
  108. int i;
  109. BOOST_CHECK(!(os << 42 << endl));
  110. BOOST_CHECK(!(is >> i));
  111. }
  112. BOOST_AUTO_TEST_CASE(coverage, *boost::unit_test::timeout(5))
  113. {
  114. //more of a syntax check, since template.
  115. {
  116. bp::pipe p1;
  117. bp::ipstream is1(p1);
  118. bp::ipstream is2(std::move(p1));
  119. is2.pipe(is1.pipe());
  120. bp::pipe p2_;
  121. bp::pipe p2 = p2_;
  122. BOOST_REQUIRE_NO_THROW(p2_ == p2);
  123. BOOST_CHECK(p2_ == p2);
  124. bp::opstream os1(p2);
  125. bp::opstream os2(std::move(p2));
  126. os2.pipe(os1.pipe());
  127. bp::pipe p3;
  128. is1 = p3;
  129. is2 = std::move(p3);
  130. bp::pipe p4_;
  131. bp::pipe p4 = std::move(p4_);
  132. bp::pipe p5;
  133. BOOST_REQUIRE_NO_THROW(p4_ != p4);
  134. BOOST_CHECK(p4_ != p4);
  135. BOOST_REQUIRE_NO_THROW(p5 != p4);
  136. BOOST_CHECK(p4 != p5);
  137. is1 = p4;
  138. is2 = std::move(p4);
  139. }
  140. {
  141. bp::wpipe p;
  142. bp::wpstream ws1(p);
  143. bp::wpstream ws2(std::move(p));
  144. ws2.pipe(std::move(ws1.pipe()));
  145. bp::wpipe p2;
  146. ws1 = p2;
  147. ws2 = std::move(p2);
  148. const bp::wpstream & ws2c = ws2;
  149. ws1.pipe(ws2c.pipe());
  150. }
  151. {
  152. bp::wpipe p;
  153. bp::wpipebuf ws1(p);
  154. bp::wpipebuf ws2(std::move(p));
  155. ws2.pipe(std::move(ws1.pipe()));
  156. bp::wpipe p2;
  157. ws1 = p2;
  158. ws2 = std::move(p2);
  159. const bp::wpipebuf & ws2c = ws2;
  160. ws1.pipe(ws2c.pipe());
  161. }
  162. }
  163. BOOST_AUTO_TEST_CASE(stream_close, *boost::unit_test::timeout(5))
  164. {
  165. bp::pipe p;
  166. int i = 1234, j = 0;
  167. bp::opstream op{p};
  168. bp::ipstream ip{p};
  169. p.close();
  170. op << i << " ";
  171. op.close();
  172. ip >> j;
  173. BOOST_CHECK_EQUAL(i, j);
  174. }
  175. BOOST_AUTO_TEST_CASE(stream_close_scope, *boost::unit_test::timeout(5))
  176. {
  177. bp::pipe p;
  178. int i = 1234, j = 0;
  179. bp::ipstream ip;
  180. {
  181. bp::opstream op{ip.pipe()};
  182. op << i << " ";
  183. }
  184. ip >> j;
  185. BOOST_CHECK_EQUAL(i, j);
  186. }
  187. BOOST_AUTO_TEST_SUITE_END();