• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <vector>
13 #include <boost/algorithm/string/predicate.hpp>
14 
15 #include <boost/process/async_pipe.hpp>
16 #include <boost/process/pipe.hpp>
17 #include <boost/asio/read.hpp>
18 #include <boost/asio/read_until.hpp>
19 #include <boost/asio/write.hpp>
20 #include <boost/asio/streambuf.hpp>
21 
22 using namespace std;
23 namespace bp = boost::process;
24 namespace asio = boost::asio;
25 
26 BOOST_AUTO_TEST_SUITE( async );
27 
28 
29 BOOST_AUTO_TEST_CASE(plain_async, *boost::unit_test::timeout(5))
30 {
31     asio::io_context ios;
32     bp::async_pipe pipe{ios};
33 
34     std::string st = "test-string\n";
35 
36     asio::streambuf buf;
37 
__anon82464aaf0102(const boost::system::error_code &, std::size_t)38     asio::async_write(pipe, asio::buffer(st), [](const boost::system::error_code &, std::size_t){});
__anon82464aaf0202(const boost::system::error_code &, std::size_t)39     asio::async_read_until(pipe, buf, '\n', [](const boost::system::error_code &, std::size_t){});
40 
41     ios.run();
42 
43     std::string line;
44     std::istream istr(&buf);
45     BOOST_CHECK(std::getline(istr, line));
46 
47     line.resize(11);
48     BOOST_CHECK_EQUAL(line, "test-string");
49 
50 }
51 
BOOST_AUTO_TEST_CASE(closed_transform)52 BOOST_AUTO_TEST_CASE(closed_transform)
53 {
54     asio::io_context ios;
55 
56     bp::async_pipe ap{ios};
57 
58     BOOST_CHECK(ap.is_open());
59     bp::pipe p2 = static_cast<bp::pipe>(ap);
60     BOOST_CHECK(p2.is_open());
61 
62     ap.close();
63     BOOST_CHECK(!ap.is_open());
64 
65     bp::pipe p  = static_cast<bp::pipe>(ap);
66     BOOST_CHECK(!p.is_open());
67 
68 }
69 
BOOST_AUTO_TEST_CASE(multithreaded_async_pipe)70 BOOST_AUTO_TEST_CASE(multithreaded_async_pipe)
71 {
72     asio::io_context ioc;
73 
74     std::vector<std::thread> threads;
75     for (int i = 0; i < std::thread::hardware_concurrency(); i++)
76     {
77         threads.emplace_back([&ioc]
78         {
79             std::vector<bp::async_pipe*> pipes;
80             for (size_t i = 0; i < 100; i++)
81                 pipes.push_back(new bp::async_pipe(ioc));
82             for (auto &p : pipes)
83                 delete p;
84         });
85     }
86     for (auto &t : threads)
87         t.join();
88 }
89 
90 
91 
BOOST_AUTO_TEST_CASE(move_pipe)92 BOOST_AUTO_TEST_CASE(move_pipe)
93 {
94     asio::io_context ios;
95 
96     bp::async_pipe ap{ios};
97     BOOST_TEST_CHECKPOINT("First move");
98     bp::async_pipe ap2{std::move(ap)};
99 #if defined(BOOST_WINDOWS_API)
100     BOOST_CHECK_EQUAL(ap.native_source(), ::boost::winapi::INVALID_HANDLE_VALUE_);
101     BOOST_CHECK_EQUAL(ap.native_sink  (), ::boost::winapi::INVALID_HANDLE_VALUE_);
102 #elif defined(BOOST_POSIX_API)
103     BOOST_CHECK_EQUAL(ap.native_source(), -1);
104     BOOST_CHECK_EQUAL(ap.native_sink  (), -1);
105 #endif
106 
107     BOOST_TEST_CHECKPOINT("Second move");
108     ap = std::move(ap2);
109 
110     {
111         BOOST_TEST_CHECKPOINT("Third move, from closed");
112         bp::async_pipe ap_inv{ios};
113         ap_inv.close();
114         ap = std::move(ap_inv);
115     }
116 
117     {
118         BOOST_TEST_CHECKPOINT("Fourth move, from closed");
119         bp::async_pipe ap_inv{ios};
120         ap_inv.close();
121         const auto ap3 = std::move(ap_inv);
122     }
123 
124     {
125         //copy an a closed pipe
126         BOOST_TEST_CHECKPOINT("Copy assign");
127         BOOST_TEST_CHECKPOINT("Fourth move, from closed");
128         bp::async_pipe ap_inv{ios};
129         ap_inv.close();
130         ap = ap_inv; //copy an invalid pipe
131     }
132 
133     {
134         //copy an a closed pipe
135         BOOST_TEST_CHECKPOINT("Copy assign");
136         BOOST_TEST_CHECKPOINT("Fourth move, from closed");
137         bp::async_pipe ap_inv{ios};
138         ap_inv.close();
139         BOOST_TEST_CHECKPOINT("Copy construct");
140         bp::async_pipe ap4{ap_inv};
141     }
142 
143 
144 }
145 
146 
147 BOOST_AUTO_TEST_SUITE_END();