]> git.proxmox.com Git - ceph.git/blob - ceph/src/Beast/extras/beast/test/fail_stream.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / Beast / extras / beast / test / fail_stream.hpp
1 //
2 // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7
8 #ifndef BEAST_TEST_FAIL_STREAM_HPP
9 #define BEAST_TEST_FAIL_STREAM_HPP
10
11 #include <beast/core/async_completion.hpp>
12 #include <beast/core/bind_handler.hpp>
13 #include <beast/core/error.hpp>
14 #include <beast/core/detail/get_lowest_layer.hpp>
15 #include <beast/websocket/teardown.hpp>
16 #include <beast/test/fail_counter.hpp>
17 #include <boost/optional.hpp>
18
19 namespace beast {
20 namespace test {
21
22 /** A stream wrapper that fails.
23
24 On the Nth operation, the stream will fail with the specified
25 error code, or the default error code of invalid_argument.
26 */
27 template<class NextLayer>
28 class fail_stream
29 {
30 boost::optional<fail_counter> fc_;
31 fail_counter* pfc_;
32 NextLayer next_layer_;
33
34 public:
35 using next_layer_type =
36 typename std::remove_reference<NextLayer>::type;
37
38 using lowest_layer_type =
39 typename beast::detail::get_lowest_layer<
40 next_layer_type>::type;
41
42 fail_stream(fail_stream&&) = delete;
43 fail_stream(fail_stream const&) = delete;
44 fail_stream& operator=(fail_stream&&) = delete;
45 fail_stream& operator=(fail_stream const&) = delete;
46
47 template<class... Args>
48 explicit
49 fail_stream(std::size_t n, Args&&... args)
50 : fc_(n)
51 , pfc_(&*fc_)
52 , next_layer_(std::forward<Args>(args)...)
53 {
54 }
55
56 template<class... Args>
57 explicit
58 fail_stream(fail_counter& fc, Args&&... args)
59 : pfc_(&fc)
60 , next_layer_(std::forward<Args>(args)...)
61 {
62 }
63
64 next_layer_type&
65 next_layer()
66 {
67 return next_layer_;
68 }
69
70 lowest_layer_type&
71 lowest_layer()
72 {
73 return next_layer_.lowest_layer();
74 }
75
76 lowest_layer_type const&
77 lowest_layer() const
78 {
79 return next_layer_.lowest_layer();
80 }
81
82 boost::asio::io_service&
83 get_io_service()
84 {
85 return next_layer_.get_io_service();
86 }
87
88 template<class MutableBufferSequence>
89 std::size_t
90 read_some(MutableBufferSequence const& buffers)
91 {
92 pfc_->fail();
93 return next_layer_.read_some(buffers);
94 }
95
96 template<class MutableBufferSequence>
97 std::size_t
98 read_some(MutableBufferSequence const& buffers, error_code& ec)
99 {
100 if(pfc_->fail(ec))
101 return 0;
102 return next_layer_.read_some(buffers, ec);
103 }
104
105 template<class MutableBufferSequence, class ReadHandler>
106 typename async_completion<
107 ReadHandler, void(error_code)>::result_type
108 async_read_some(MutableBufferSequence const& buffers,
109 ReadHandler&& handler)
110 {
111 error_code ec;
112 if(pfc_->fail(ec))
113 {
114 async_completion<
115 ReadHandler, void(error_code, std::size_t)
116 > completion{handler};
117 next_layer_.get_io_service().post(
118 bind_handler(completion.handler, ec, 0));
119 return completion.result.get();
120 }
121 return next_layer_.async_read_some(buffers,
122 std::forward<ReadHandler>(handler));
123 }
124
125 template<class ConstBufferSequence>
126 std::size_t
127 write_some(ConstBufferSequence const& buffers)
128 {
129 pfc_->fail();
130 return next_layer_.write_some(buffers);
131 }
132
133 template<class ConstBufferSequence>
134 std::size_t
135 write_some(ConstBufferSequence const& buffers, error_code& ec)
136 {
137 if(pfc_->fail(ec))
138 return 0;
139 return next_layer_.write_some(buffers, ec);
140 }
141
142 template<class ConstBufferSequence, class WriteHandler>
143 typename async_completion<
144 WriteHandler, void(error_code)>::result_type
145 async_write_some(ConstBufferSequence const& buffers,
146 WriteHandler&& handler)
147 {
148 error_code ec;
149 if(pfc_->fail(ec))
150 {
151 async_completion<
152 WriteHandler, void(error_code, std::size_t)
153 > completion{handler};
154 next_layer_.get_io_service().post(
155 bind_handler(completion.handler, ec, 0));
156 return completion.result.get();
157 }
158 return next_layer_.async_write_some(buffers,
159 std::forward<WriteHandler>(handler));
160 }
161
162 friend
163 void
164 teardown(websocket::teardown_tag,
165 fail_stream<NextLayer>& stream,
166 boost::system::error_code& ec)
167 {
168 if(stream.pfc_->fail(ec))
169 return;
170 beast::websocket_helpers::call_teardown(stream.next_layer(), ec);
171 }
172
173 template<class TeardownHandler>
174 friend
175 void
176 async_teardown(websocket::teardown_tag,
177 fail_stream<NextLayer>& stream,
178 TeardownHandler&& handler)
179 {
180 error_code ec;
181 if(stream.pfc_->fail(ec))
182 {
183 stream.get_io_service().post(
184 bind_handler(std::move(handler), ec));
185 return;
186 }
187 beast::websocket_helpers::call_async_teardown(
188 stream.next_layer(), std::forward<TeardownHandler>(handler));
189 }
190 };
191
192 } // test
193 } // beast
194
195 #endif