]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // error_code_test.cpp -----------------------------------------------------// |
2 | ||
3 | // Copyright Beman Dawes 2006 | |
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 | // See library home page at http://www.boost.org/libs/system | |
9 | ||
10 | //----------------------------------------------------------------------------// | |
11 | ||
7c673cae FG |
12 | #include <boost/config/warning_disable.hpp> |
13 | ||
14 | #include <boost/detail/lightweight_test.hpp> | |
15 | #include <boost/system/error_code.hpp> | |
16 | #include <boost/system/cygwin_error.hpp> | |
17 | #include <boost/system/linux_error.hpp> | |
18 | #include <boost/system/windows_error.hpp> | |
19 | #include <iostream> | |
20 | #include <sstream> | |
21 | #include <string> | |
22 | #include <cstring> | |
23 | #include <functional> | |
24 | #include <boost/cerrno.hpp> | |
25 | ||
26 | // Although using directives are not the best programming practice, testing | |
27 | // with a boost::system using directive increases use scenario coverage. | |
28 | using namespace boost::system; | |
29 | ||
b32b8144 FG |
30 | #if defined( BOOST_WINDOWS_API ) |
31 | // Neither MinGW or Cygwin versions of winerror.h work if used alone, so on | |
32 | // either of those platforms include the full windows.h | |
33 | # if defined(__MINGW32__) || defined(__CYGWIN__) | |
34 | # include <windows.h> | |
35 | # else | |
36 | # include <winerror.h> | |
37 | # endif | |
38 | # define BOOST_ACCESS_ERROR_MACRO ERROR_ACCESS_DENIED | |
39 | #elif defined( BOOST_POSIX_API ) | |
40 | # define BOOST_ACCESS_ERROR_MACRO EACCES | |
41 | #else | |
42 | # error "Only supported for POSIX and Windows" | |
43 | #endif | |
7c673cae FG |
44 | |
45 | namespace | |
46 | { | |
47 | void check_ostream( error_code ec, const char * expected ) | |
48 | { | |
49 | std::stringstream ss; | |
50 | std::string s; | |
51 | ||
52 | ss << ec; | |
53 | ss >> s; | |
54 | BOOST_TEST( s == expected ); | |
55 | } | |
b32b8144 FG |
56 | |
57 | // throws_function_test ------------------------------------------------------------// | |
58 | ||
59 | // usage example | |
60 | ||
61 | int divide(int dividend, int divisor, boost::system::error_code& ec = boost::throws()) | |
62 | { | |
63 | if (divisor == 0) // is there an error? | |
64 | { | |
65 | if (&ec == &boost::throws()) // throw on error | |
66 | throw "oops!"; // whatever exception you prefer | |
67 | ec = error_code(EDOM, generic_category()); // report error via error_code | |
68 | return 0; | |
69 | } | |
70 | ||
71 | if (&ec != &boost::throws()) // error reporting via error_code | |
72 | ec.clear(); | |
73 | return dividend / divisor; | |
74 | } | |
75 | ||
76 | // test usage example | |
77 | ||
78 | void test_throws_usage() | |
79 | { | |
80 | std::cout << "Test throws() example and usage...\n"; | |
81 | error_code ec; | |
82 | ||
83 | // no error tests | |
84 | BOOST_TEST_EQ((divide(10, 2)), 5); // no error, report via exception | |
85 | ec = make_error_code(errc::argument_out_of_domain); | |
86 | BOOST_TEST_EQ((divide(10, 5, ec)), 2); // no error, report via error_code | |
87 | BOOST_TEST(!ec); | |
88 | ||
89 | ec = make_error_code(errc::argument_out_of_domain); | |
90 | BOOST_TEST_EQ((divide(10, 0, ec)), 0); // error, report via error_code | |
91 | BOOST_TEST(ec); | |
92 | ||
93 | bool exception_thrown = false; | |
94 | try | |
95 | { divide(10, 0); } // error, report via exception | |
96 | catch (...) | |
97 | { exception_thrown = true; } | |
98 | BOOST_TEST(exception_thrown); | |
99 | ||
100 | //error_code should_fail(boost::throws()); // should fail at runtime | |
101 | //boost::throws() = ec; // should fail at runtime | |
102 | } | |
7c673cae FG |
103 | } |
104 | ||
105 | // main ------------------------------------------------------------------------------// | |
106 | ||
107 | // TODO: add hash_value tests | |
108 | ||
109 | int main( int, char ** ) | |
110 | { | |
111 | ||
112 | std::cout << "Conversion use cases...\n"; | |
113 | error_condition x1( errc::file_exists ); | |
114 | //error_code x2( errc::file_exists ); // should fail to compile | |
115 | make_error_code(errc::file_exists); | |
116 | make_error_condition(errc::file_exists); | |
117 | ||
118 | std::cout << "General tests...\n"; | |
119 | // unit tests: | |
120 | ||
121 | BOOST_TEST( generic_category() == generic_category() ); | |
122 | BOOST_TEST( system_category() == system_category() ); | |
123 | BOOST_TEST( generic_category() != system_category() ); | |
124 | BOOST_TEST( system_category() != generic_category() ); | |
125 | ||
92f5a8d4 | 126 | BOOST_TEST_NE( generic_category() < system_category(), system_category() < generic_category() ); |
7c673cae FG |
127 | |
128 | error_code ec; | |
129 | error_condition econd; | |
130 | BOOST_TEST( !ec ); | |
131 | BOOST_TEST( ec.value() == 0 ); | |
132 | econd = ec.default_error_condition(); | |
133 | BOOST_TEST( econd.value() == 0 ); | |
134 | BOOST_TEST( econd.category() == generic_category() ); | |
135 | BOOST_TEST( ec == errc::success ); | |
136 | BOOST_TEST( ec.category() == system_category() ); | |
137 | BOOST_TEST( std::strcmp( ec.category().name(), "system") == 0 ); | |
138 | BOOST_TEST( !(ec < error_code( 0, system_category() )) ); | |
139 | BOOST_TEST( !(error_code( 0, system_category() ) < ec) ); | |
140 | BOOST_TEST( ec < error_code( 1, system_category() ) ); | |
141 | BOOST_TEST( !(error_code( 1, system_category() ) < ec) ); | |
142 | ||
143 | error_code ec_0_system( 0, system_category() ); | |
144 | BOOST_TEST( !ec_0_system ); | |
145 | BOOST_TEST( ec_0_system.value() == 0 ); | |
146 | econd = ec_0_system.default_error_condition(); | |
147 | BOOST_TEST( econd.value() == 0 ); | |
148 | BOOST_TEST( econd.category() == generic_category() ); | |
149 | BOOST_TEST( ec_0_system == errc::success ); | |
150 | BOOST_TEST( ec_0_system.category() == system_category() ); | |
151 | BOOST_TEST( std::strcmp( ec_0_system.category().name(), "system") == 0 ); | |
152 | check_ostream( ec_0_system, "system:0" ); | |
153 | ||
154 | BOOST_TEST( ec_0_system == ec ); | |
155 | ||
156 | error_code ec_1_system( 1, system_category() ); | |
157 | BOOST_TEST( ec_1_system ); | |
158 | BOOST_TEST( ec_1_system.value() == 1 ); | |
159 | BOOST_TEST( ec_1_system.value() != 0 ); | |
160 | BOOST_TEST( ec != ec_1_system ); | |
161 | BOOST_TEST( ec_0_system != ec_1_system ); | |
162 | check_ostream( ec_1_system, "system:1" ); | |
163 | ||
164 | ec = error_code( BOOST_ACCESS_ERROR_MACRO, system_category() ); | |
165 | BOOST_TEST( ec ); | |
166 | BOOST_TEST( ec.value() == BOOST_ACCESS_ERROR_MACRO ); | |
167 | econd = ec.default_error_condition(); | |
168 | BOOST_TEST( econd.value() == static_cast<int>(errc::permission_denied) ); | |
169 | BOOST_TEST( econd.category() == generic_category() ); | |
170 | BOOST_TEST( econd == error_condition( errc::permission_denied, generic_category() ) ); | |
171 | BOOST_TEST( econd == errc::permission_denied ); | |
172 | BOOST_TEST( errc::permission_denied == econd ); | |
173 | BOOST_TEST( ec == errc::permission_denied ); | |
174 | BOOST_TEST( ec.category() == system_category() ); | |
175 | BOOST_TEST( std::strcmp( ec.category().name(), "system") == 0 ); | |
176 | ||
177 | // test the explicit make_error_code conversion for errc | |
178 | ec = make_error_code( errc::bad_message ); | |
179 | BOOST_TEST( ec ); | |
180 | BOOST_TEST( ec == errc::bad_message ); | |
181 | BOOST_TEST( errc::bad_message == ec ); | |
182 | BOOST_TEST( ec != errc::permission_denied ); | |
183 | BOOST_TEST( errc::permission_denied != ec ); | |
184 | BOOST_TEST( ec.category() == generic_category() ); | |
185 | ||
186 | //// test the deprecated predefined error_category synonyms | |
187 | //BOOST_TEST( &system_category() == &native_ecat ); | |
188 | //BOOST_TEST( &generic_category() == &errno_ecat ); | |
189 | //BOOST_TEST( system_category() == native_ecat ); | |
190 | //BOOST_TEST( generic_category() == errno_ecat ); | |
191 | ||
192 | // test error_code and error_condition message(); | |
193 | // see Boost.Filesystem operations_test for code specific message() tests | |
194 | ec = error_code( -1, system_category() ); | |
195 | std::cout << "error_code message for -1 is \"" << ec.message() << "\"\n"; | |
196 | std::cout << "error_code message for 0 is \"" << ec_0_system.message() << "\"\n"; | |
197 | #if defined(BOOST_WINDOWS_API) | |
198 | // Borland appends newline, so just check text | |
199 | BOOST_TEST( ec.message().substr(0,13) == "Unknown error" ); | |
92f5a8d4 TL |
200 | // Fails when the language isn't US English |
201 | // BOOST_TEST( ec_0_system.message().substr(0,36) == "The operation completed successfully" ); | |
7c673cae FG |
202 | #elif defined(linux) || defined(__linux) || defined(__linux__) |
203 | // Linux appends value to message as unsigned, so it varies with # of bits | |
204 | BOOST_TEST( ec.message().substr(0,13) == "Unknown error" ); | |
205 | #elif defined(__hpux) | |
206 | BOOST_TEST( ec.message() == "" ); | |
207 | #elif defined(__osf__) | |
208 | BOOST_TEST( ec.message() == "Error -1 occurred." ); | |
209 | #elif defined(__vms) | |
210 | BOOST_TEST( ec.message() == "error -1" ); | |
211 | #endif | |
212 | ||
213 | ec = error_code( BOOST_ACCESS_ERROR_MACRO, system_category() ); | |
214 | BOOST_TEST( ec.message() != "" ); | |
215 | BOOST_TEST( ec.message().substr( 0, 13) != "Unknown error" ); | |
216 | ||
217 | econd = error_condition( -1, generic_category() ); | |
218 | error_condition econd_ok; | |
219 | std::cout << "error_condition message for -1 is \"" << econd.message() << "\"\n"; | |
220 | std::cout << "error_condition message for 0 is \"" << econd_ok.message() << "\"\n"; | |
221 | #if defined(BOOST_WINDOWS_API) | |
222 | // Borland appends newline, so just check text | |
223 | BOOST_TEST( econd.message().substr(0,13) == "Unknown error" ); | |
224 | BOOST_TEST( econd_ok.message().substr(0,8) == "No error" ); | |
225 | #elif defined(linux) || defined(__linux) || defined(__linux__) | |
226 | // Linux appends value to message as unsigned, so it varies with # of bits | |
227 | BOOST_TEST( econd.message().substr(0,13) == "Unknown error" ); | |
228 | #elif defined(__hpux) | |
229 | BOOST_TEST( econd.message() == "" ); | |
230 | #elif defined(__osf__) | |
231 | BOOST_TEST( econd.message() == "Error -1 occurred." ); | |
232 | #elif defined(__vms) | |
233 | BOOST_TEST( econd.message() == "error -1" ); | |
234 | #endif | |
235 | ||
236 | econd = error_condition( BOOST_ACCESS_ERROR_MACRO, generic_category() ); | |
237 | BOOST_TEST( econd.message() != "" ); | |
238 | BOOST_TEST( econd.message().substr( 0, 13) != "Unknown error" ); | |
239 | ||
b32b8144 FG |
240 | test_throws_usage(); |
241 | ||
7c673cae FG |
242 | #ifdef BOOST_WINDOWS_API |
243 | std::cout << "Windows tests...\n"; | |
244 | // these tests probe the Windows errc decoder | |
245 | // test the first entry in the decoder table: | |
246 | ec = error_code( ERROR_ACCESS_DENIED, system_category() ); | |
247 | BOOST_TEST( ec.value() == ERROR_ACCESS_DENIED ); | |
248 | BOOST_TEST( ec == errc::permission_denied ); | |
249 | BOOST_TEST( ec.default_error_condition().value() == errc::permission_denied ); | |
250 | BOOST_TEST( ec.default_error_condition().category() == generic_category() ); | |
251 | ||
252 | // test the second entry in the decoder table: | |
253 | ec = error_code( ERROR_ALREADY_EXISTS, system_category() ); | |
254 | BOOST_TEST( ec.value() == ERROR_ALREADY_EXISTS ); | |
255 | BOOST_TEST( ec == errc::file_exists ); | |
256 | BOOST_TEST( ec.default_error_condition().value() == errc::file_exists ); | |
257 | BOOST_TEST( ec.default_error_condition().category() == generic_category() ); | |
258 | ||
259 | // test the third entry in the decoder table: | |
260 | ec = error_code( ERROR_BAD_UNIT, system_category() ); | |
261 | BOOST_TEST( ec.value() == ERROR_BAD_UNIT ); | |
262 | BOOST_TEST( ec == errc::no_such_device ); | |
263 | BOOST_TEST( ec.default_error_condition().value() == errc::no_such_device ); | |
264 | BOOST_TEST( ec.default_error_condition().category() == generic_category() ); | |
265 | ||
266 | // test the last non-Winsock entry in the decoder table: | |
267 | ec = error_code( ERROR_WRITE_PROTECT, system_category() ); | |
268 | BOOST_TEST( ec.value() == ERROR_WRITE_PROTECT ); | |
269 | BOOST_TEST( ec == errc::permission_denied ); | |
270 | BOOST_TEST( ec.default_error_condition().value() == errc::permission_denied ); | |
271 | BOOST_TEST( ec.default_error_condition().category() == generic_category() ); | |
272 | ||
273 | // test the last Winsock entry in the decoder table: | |
274 | ec = error_code( WSAEWOULDBLOCK, system_category() ); | |
275 | BOOST_TEST( ec.value() == WSAEWOULDBLOCK ); | |
276 | BOOST_TEST( ec == errc::operation_would_block ); | |
277 | BOOST_TEST( ec.default_error_condition().value() == errc::operation_would_block ); | |
278 | BOOST_TEST( ec.default_error_condition().category() == generic_category() ); | |
279 | ||
280 | // test not-in-table condition: | |
281 | ec = error_code( 1234567890, system_category() ); | |
282 | BOOST_TEST( ec.value() == 1234567890 ); | |
283 | BOOST_TEST( ec.default_error_condition().value() == 1234567890 ); | |
284 | BOOST_TEST( ec.default_error_condition().category() == system_category() ); | |
285 | ||
286 | #else // POSIX | |
287 | ||
288 | std::cout << "POSIX tests...\n"; | |
289 | ec = error_code( EACCES, system_category() ); | |
290 | BOOST_TEST( ec == error_code( errc::permission_denied, system_category() ) ); | |
291 | BOOST_TEST( error_code( errc::permission_denied, system_category() ) == ec ); | |
292 | BOOST_TEST( ec == errc::permission_denied ); | |
293 | BOOST_TEST( errc::permission_denied == ec ); | |
294 | BOOST_TEST( ec.default_error_condition().value() == errc::permission_denied ); | |
295 | BOOST_TEST( ec.default_error_condition().category() == generic_category() ); | |
296 | ||
297 | # ifdef __CYGWIN__ | |
298 | ||
299 | std::cout << "Cygwin tests...\n"; | |
300 | ec = cygwin_error::no_package; | |
301 | BOOST_TEST( ec == cygwin_error::no_package ); | |
302 | BOOST_TEST( ec == error_code( ENOPKG, system_category() ) ); | |
303 | BOOST_TEST( ec == error_code( cygwin_error::no_package, system_category() ) ); | |
304 | BOOST_TEST( ec.default_error_condition().category() == system_category() ); | |
305 | ||
306 | # elif defined(linux) || defined(__linux) || defined(__linux__) | |
307 | ||
308 | std::cout << "Linux tests...\n"; | |
309 | ec = linux_error::dot_dot_error; | |
310 | BOOST_TEST( ec == linux_error::dot_dot_error ); | |
311 | BOOST_TEST( ec == error_code( EDOTDOT, system_category() ) ); | |
312 | BOOST_TEST( ec == error_code( linux_error::dot_dot_error, system_category() ) ); | |
313 | BOOST_TEST( ec.default_error_condition().category() == system_category() ); | |
314 | ||
315 | # endif | |
316 | ||
317 | #endif | |
318 | ||
319 | return ::boost::report_errors(); | |
320 | } | |
321 | ||
322 |