]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/test/extras/include/boost/beast/test/fail_counter.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / beast / test / extras / include / boost / beast / test / fail_counter.hpp
1 //
2 // Copyright (c) 2016-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 // Official repository: https://github.com/boostorg/beast
8 //
9
10 #ifndef BOOST_BEAST_TEST_FAIL_COUNTER_HPP
11 #define BOOST_BEAST_TEST_FAIL_COUNTER_HPP
12
13 #include <boost/beast/core/error.hpp>
14 #include <boost/throw_exception.hpp>
15
16 namespace boost {
17 namespace beast {
18 namespace test {
19
20 enum class error
21 {
22 fail_error = 1
23 };
24
25 namespace detail {
26
27 class fail_error_category : public boost::system::error_category
28 {
29 public:
30 const char*
31 name() const noexcept override
32 {
33 return "test";
34 }
35
36 std::string
37 message(int ev) const override
38 {
39 switch(static_cast<error>(ev))
40 {
41 default:
42 case error::fail_error:
43 return "test error";
44 }
45 }
46
47 boost::system::error_condition
48 default_error_condition(int ev) const noexcept override
49 {
50 return boost::system::error_condition{ev, *this};
51 }
52
53 bool
54 equivalent(int ev,
55 boost::system::error_condition const& condition
56 ) const noexcept override
57 {
58 return condition.value() == ev &&
59 &condition.category() == this;
60 }
61
62 bool
63 equivalent(error_code const& error, int ev) const noexcept override
64 {
65 return error.value() == ev &&
66 &error.category() == this;
67 }
68 };
69
70 inline
71 boost::system::error_category const&
72 get_error_category()
73 {
74 static fail_error_category const cat{};
75 return cat;
76 }
77
78 } // detail
79
80 inline
81 error_code
82 make_error_code(error ev)
83 {
84 return error_code{
85 static_cast<std::underlying_type<error>::type>(ev),
86 detail::get_error_category()};
87 }
88
89 /** An error code with an error set on default construction
90
91 Default constructed versions of this object will have
92 an error code set right away. This helps tests find code
93 which forgets to clear the error code on success.
94 */
95 struct fail_error_code : error_code
96 {
97 fail_error_code()
98 : error_code(make_error_code(error::fail_error))
99 {
100 }
101
102 template<class Arg0, class... ArgN>
103 fail_error_code(Arg0&& arg0, ArgN&&... argn)
104 : error_code(arg0, std::forward<ArgN>(argn)...)
105 {
106 }
107 };
108
109 /** A countdown to simulated failure.
110
111 On the Nth operation, the class will fail with the specified
112 error code, or the default error code of @ref error::fail_error.
113 */
114 class fail_counter
115 {
116 std::size_t n_;
117 std::size_t i_ = 0;
118 error_code ec_;
119
120 public:
121 fail_counter(fail_counter&&) = default;
122
123 /** Construct a counter.
124
125 @param The 0-based index of the operation to fail on or after.
126 */
127 explicit
128 fail_counter(std::size_t n,
129 error_code ev = make_error_code(error::fail_error))
130 : n_(n)
131 , ec_(ev)
132 {
133 }
134
135 /// Returns the fail index
136 std::size_t
137 count() const
138 {
139 return n_;
140 }
141
142 /// Throw an exception on the Nth failure
143 void
144 fail()
145 {
146 if(i_ < n_)
147 ++i_;
148 if(i_ == n_)
149 BOOST_THROW_EXCEPTION(system_error{ec_});
150 }
151
152 /// Set an error code on the Nth failure
153 bool
154 fail(error_code& ec)
155 {
156 if(i_ < n_)
157 ++i_;
158 if(i_ == n_)
159 {
160 ec = ec_;
161 return true;
162 }
163 ec.assign(0, ec.category());
164 return false;
165 }
166 };
167
168 } // test
169 } // beast
170 } // boost
171
172 namespace boost {
173 namespace system {
174 template<>
175 struct is_error_code_enum<beast::test::error>
176 {
177 static bool const value = true;
178 };
179 } // system
180 } // boost
181
182 #endif