]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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_COUNTER_HPP | |
9 | #define BEAST_TEST_FAIL_COUNTER_HPP | |
10 | ||
11 | #include <beast/core/error.hpp> | |
12 | ||
13 | namespace beast { | |
14 | namespace test { | |
15 | ||
16 | enum class error | |
17 | { | |
18 | fail_error = 1 | |
19 | }; | |
20 | ||
21 | namespace detail { | |
22 | ||
23 | class fail_error_category : public boost::system::error_category | |
24 | { | |
25 | public: | |
26 | const char* | |
27 | name() const noexcept override | |
28 | { | |
29 | return "test"; | |
30 | } | |
31 | ||
32 | std::string | |
33 | message(int ev) const override | |
34 | { | |
35 | switch(static_cast<error>(ev)) | |
36 | { | |
37 | default: | |
38 | case error::fail_error: | |
39 | return "test error"; | |
40 | } | |
41 | } | |
42 | ||
43 | boost::system::error_condition | |
44 | default_error_condition(int ev) const noexcept override | |
45 | { | |
46 | return boost::system::error_condition{ev, *this}; | |
47 | } | |
48 | ||
49 | bool | |
50 | equivalent(int ev, | |
51 | boost::system::error_condition const& condition | |
52 | ) const noexcept override | |
53 | { | |
54 | return condition.value() == ev && | |
55 | &condition.category() == this; | |
56 | } | |
57 | ||
58 | bool | |
59 | equivalent(error_code const& error, int ev) const noexcept override | |
60 | { | |
61 | return error.value() == ev && | |
62 | &error.category() == this; | |
63 | } | |
64 | }; | |
65 | ||
66 | inline | |
67 | boost::system::error_category const& | |
68 | get_error_category() | |
69 | { | |
70 | static fail_error_category const cat{}; | |
71 | return cat; | |
72 | } | |
73 | ||
74 | } // detail | |
75 | ||
76 | inline | |
77 | error_code | |
78 | make_error_code(error ev) | |
79 | { | |
80 | return error_code{ | |
81 | static_cast<std::underlying_type<error>::type>(ev), | |
82 | detail::get_error_category()}; | |
83 | } | |
84 | ||
85 | /** A countdown to simulated failure. | |
86 | ||
87 | On the Nth operation, the class will fail with the specified | |
88 | error code, or the default error code of @ref error::fail_error. | |
89 | */ | |
90 | class fail_counter | |
91 | { | |
92 | std::size_t n_; | |
93 | error_code ec_; | |
94 | ||
95 | public: | |
96 | fail_counter(fail_counter&&) = default; | |
97 | ||
98 | /** Construct a counter. | |
99 | ||
100 | @param The 0-based index of the operation to fail on or after. | |
101 | */ | |
102 | explicit | |
103 | fail_counter(std::size_t n, | |
104 | error_code ev = make_error_code(error::fail_error)) | |
105 | : n_(n) | |
106 | , ec_(ev) | |
107 | { | |
108 | } | |
109 | ||
110 | /// Throw an exception on the Nth failure | |
111 | void | |
112 | fail() | |
113 | { | |
114 | if(n_ > 0) | |
115 | --n_; | |
116 | if(! n_) | |
117 | throw system_error{ec_}; | |
118 | } | |
119 | ||
120 | /// Set an error code on the Nth failure | |
121 | bool | |
122 | fail(error_code& ec) | |
123 | { | |
124 | if(n_ > 0) | |
125 | --n_; | |
126 | if(! n_) | |
127 | { | |
128 | ec = ec_; | |
129 | return true; | |
130 | } | |
131 | return false; | |
132 | } | |
133 | }; | |
134 | ||
135 | } // test | |
136 | } // beast | |
137 | ||
138 | namespace boost { | |
139 | namespace system { | |
140 | template<> | |
141 | struct is_error_code_enum<beast::test::error> | |
142 | { | |
143 | static bool const value = true; | |
144 | }; | |
145 | } // system | |
146 | } // boost | |
147 | ||
148 | #endif |