Skip to content

Commit 716a55c

Browse files
committed
port beast testing tools
1 parent cfd6c6f commit 716a55c

File tree

9 files changed

+1794
-0
lines changed

9 files changed

+1794
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//
2+
// Copyright (c) 2016-2019 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+
// Official repository: https://github.com/cppaliance/http_io
8+
//
9+
10+
#ifndef BOOST_HTTP_IO_TEST_DETAIL_SERVICE_BASE_HPP
11+
#define BOOST_HTTP_IO_TEST_DETAIL_SERVICE_BASE_HPP
12+
13+
#include <boost/asio/execution_context.hpp>
14+
15+
namespace boost {
16+
namespace http_io {
17+
namespace test {
18+
namespace detail {
19+
20+
template<class T>
21+
struct service_base : asio::execution_context::service
22+
{
23+
static asio::execution_context::id const id;
24+
25+
explicit
26+
service_base(asio::execution_context& ctx)
27+
: asio::execution_context::service(ctx)
28+
{
29+
}
30+
};
31+
32+
template<class T>
33+
asio::execution_context::id const service_base<T>::id;
34+
35+
} // detail
36+
} // test
37+
} // http_io
38+
} // boost
39+
40+
#endif
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
//
2+
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3+
// Copyright (c) 2020 Richard Hodges ([email protected])
4+
//
5+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7+
//
8+
// Official repository: https://github.com/cppaliance/http_io
9+
//
10+
11+
#ifndef BOOST_HTTP_IO_TEST_DETAIL_STREAM_STATE_HPP
12+
#define BOOST_HTTP_IO_TEST_DETAIL_STREAM_STATE_HPP
13+
14+
#include <boost/asio/any_io_executor.hpp>
15+
#include <boost/asio/error.hpp>
16+
#include <boost/buffers/string_buffer.hpp>
17+
#include <boost/http_io/detail/config.hpp>
18+
#include <boost/http_io/test/detail/service_base.hpp>
19+
#include <boost/http_io/test/error.hpp>
20+
#include <boost/http_io/test/fail_count.hpp>
21+
#include <boost/make_shared.hpp>
22+
#include <boost/smart_ptr/weak_ptr.hpp>
23+
24+
#include <condition_variable>
25+
#include <memory>
26+
#include <mutex>
27+
#include <vector>
28+
29+
namespace boost {
30+
namespace http_io {
31+
namespace test {
32+
namespace detail {
33+
34+
struct stream_state;
35+
36+
struct stream_service_impl
37+
{
38+
std::mutex m_;
39+
std::vector<stream_state*> v_;
40+
41+
void
42+
remove(stream_state& impl);
43+
};
44+
45+
//------------------------------------------------------------------------------
46+
47+
class stream_service
48+
: public http_io::test::detail::service_base<stream_service>
49+
{
50+
boost::shared_ptr<detail::stream_service_impl> sp_;
51+
52+
void
53+
shutdown() override;
54+
55+
public:
56+
explicit
57+
stream_service(asio::execution_context& ctx);
58+
59+
static
60+
auto
61+
make_impl(
62+
asio::any_io_executor exec,
63+
test::fail_count* fc) ->
64+
boost::shared_ptr<detail::stream_state>;
65+
};
66+
67+
//------------------------------------------------------------------------------
68+
69+
struct stream_read_op_base
70+
{
71+
virtual ~stream_read_op_base() = default;
72+
virtual void operator()(system::error_code ec) = 0;
73+
};
74+
75+
//------------------------------------------------------------------------------
76+
77+
enum class stream_status
78+
{
79+
ok,
80+
eof,
81+
};
82+
83+
//------------------------------------------------------------------------------
84+
85+
struct stream_state
86+
{
87+
asio::any_io_executor exec;
88+
boost::weak_ptr<stream_service_impl> wp;
89+
std::mutex m;
90+
std::string storage;
91+
buffers::string_buffer b;
92+
std::condition_variable cv;
93+
std::unique_ptr<stream_read_op_base> op;
94+
stream_status code = stream_status::ok;
95+
fail_count* fc = nullptr;
96+
std::size_t nread = 0;
97+
std::size_t nread_bytes = 0;
98+
std::size_t nwrite = 0;
99+
std::size_t nwrite_bytes = 0;
100+
std::size_t read_max =
101+
(std::numeric_limits<std::size_t>::max)();
102+
std::size_t write_max =
103+
(std::numeric_limits<std::size_t>::max)();
104+
105+
stream_state(
106+
asio::any_io_executor exec_,
107+
boost::weak_ptr<stream_service_impl> wp_,
108+
fail_count* fc_);
109+
110+
stream_state(stream_state&&) = delete;
111+
112+
~stream_state();
113+
114+
void
115+
remove() noexcept;
116+
117+
void
118+
notify_read();
119+
120+
void
121+
cancel_read();
122+
};
123+
124+
//------------------------------------------------------------------------------
125+
126+
inline
127+
stream_service::
128+
stream_service(asio::execution_context& ctx)
129+
: http_io::test::detail::service_base<stream_service>(ctx)
130+
, sp_(boost::make_shared<stream_service_impl>())
131+
{
132+
}
133+
134+
inline
135+
void
136+
stream_service::
137+
shutdown()
138+
{
139+
std::vector<std::unique_ptr<detail::stream_read_op_base>> v;
140+
std::lock_guard<std::mutex> g1(sp_->m_);
141+
v.reserve(sp_->v_.size());
142+
for(auto p : sp_->v_)
143+
{
144+
std::lock_guard<std::mutex> g2(p->m);
145+
v.emplace_back(std::move(p->op));
146+
p->code = detail::stream_status::eof;
147+
}
148+
}
149+
150+
inline
151+
auto
152+
stream_service::
153+
make_impl(
154+
asio::any_io_executor exec,
155+
test::fail_count* fc) ->
156+
boost::shared_ptr<detail::stream_state>
157+
{
158+
#if defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
159+
auto& ctx = exec.context();
160+
#else
161+
auto& ctx = asio::query(
162+
exec,
163+
asio::execution::context);
164+
#endif
165+
auto& svc = asio::use_service<stream_service>(ctx);
166+
auto sp = boost::make_shared<detail::stream_state>(exec, svc.sp_, fc);
167+
std::lock_guard<std::mutex> g(svc.sp_->m_);
168+
svc.sp_->v_.push_back(sp.get());
169+
return sp;
170+
}
171+
172+
//------------------------------------------------------------------------------
173+
174+
inline
175+
void
176+
stream_service_impl::
177+
remove(stream_state& impl)
178+
{
179+
std::lock_guard<std::mutex> g(m_);
180+
*std::find(
181+
v_.begin(), v_.end(),
182+
&impl) = std::move(v_.back());
183+
v_.pop_back();
184+
}
185+
186+
//------------------------------------------------------------------------------
187+
188+
inline
189+
stream_state::
190+
stream_state(
191+
asio::any_io_executor exec_,
192+
boost::weak_ptr<stream_service_impl> wp_,
193+
fail_count* fc_)
194+
: exec(std::move(exec_))
195+
, wp(std::move(wp_))
196+
, b(&storage)
197+
, fc(fc_)
198+
{
199+
}
200+
201+
inline
202+
stream_state::
203+
~stream_state()
204+
{
205+
// cancel outstanding read
206+
if(op != nullptr)
207+
(*op)(asio::error::operation_aborted);
208+
}
209+
210+
inline
211+
void
212+
stream_state::
213+
remove() noexcept
214+
{
215+
auto sp = wp.lock();
216+
217+
// If this goes off, it means the lifetime of a test::stream object
218+
// extended beyond the lifetime of the associated execution context.
219+
BOOST_ASSERT(sp);
220+
221+
sp->remove(*this);
222+
}
223+
224+
inline
225+
void
226+
stream_state::
227+
notify_read()
228+
{
229+
if(op)
230+
{
231+
auto op_ = std::move(op);
232+
op_->operator()(system::error_code{});
233+
}
234+
else
235+
{
236+
cv.notify_all();
237+
}
238+
}
239+
240+
inline
241+
void
242+
stream_state::
243+
cancel_read()
244+
{
245+
std::unique_ptr<stream_read_op_base> p;
246+
{
247+
std::lock_guard<std::mutex> lock(m);
248+
code = stream_status::eof;
249+
p = std::move(op);
250+
}
251+
if(p != nullptr)
252+
(*p)(asio::error::operation_aborted);
253+
}
254+
255+
} // detail
256+
} // test
257+
} // http_io
258+
} // boost
259+
260+
#endif
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// Copyright (c) 2016-2019 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+
// Official repository: https://github.com/cppaliance/http_io
8+
//
9+
10+
#ifndef BOOST_HTTP_IO_TEST_ERROR_HPP
11+
#define BOOST_HTTP_IO_TEST_ERROR_HPP
12+
13+
namespace boost {
14+
namespace http_io {
15+
namespace test {
16+
17+
/// Error codes returned from unit testing algorithms
18+
enum class error
19+
{
20+
/** The test stream generated a simulated testing error
21+
22+
This error is returned by a @ref fail_count object
23+
when it generates a simulated error.
24+
*/
25+
test_failure = 1
26+
};
27+
28+
} // test
29+
} // http_io
30+
} // boost
31+
32+
#include <boost/http_io/test/impl/error.hpp>
33+
34+
#endif

0 commit comments

Comments
 (0)