Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / test / test / errors_handling_test.cpp
1 //  (C) Copyright Gennadiy Rozental 2001-2008.
2 //  (C) Copyright Beman Dawes 2001.
3 //  Distributed under the Boost Software License, Version 1.0.
4 //  (See accompanying file LICENSE_1_0.txt or copy at
5 //  http://www.boost.org/LICENSE_1_0.txt)
6
7
8 //  See http://www.boost.org/libs/test for the library home page.
9 //
10 //  File        : $RCSfile$
11 //
12 //  Version     : $Revision$
13 //
14 //  Description : tests an ability of Unit Test Framework to catch all kinds
15 //  of test errors in a user code and properly report it.
16 // ***************************************************************************
17
18 // Boost.Test
19 #define BOOST_TEST_MAIN
20 #include <boost/test/unit_test.hpp>
21 #include <boost/test/output_test_stream.hpp>
22 #include <boost/test/unit_test_log.hpp>
23 #include <boost/test/unit_test_suite.hpp>
24 #include <boost/test/framework.hpp>
25 #include <boost/test/detail/unit_test_parameters.hpp>
26 #include <boost/test/output/compiler_log_formatter.hpp>
27 #include <boost/test/results_reporter.hpp>
28
29 // STL
30 #include <iostream>
31 #include <stdexcept>
32
33 using namespace boost::unit_test;
34 using namespace boost::test_tools;
35
36 #if defined(__GNUC__) || defined(__SUNPRO_CC) || defined(__DECCXX_VER)
37 #define LIMITED_TEST
38 #endif
39
40 namespace {
41
42 struct this_test_log_formatter : public boost::unit_test::output::compiler_log_formatter
43 {
44     void    print_prefix( std::ostream& output, boost::unit_test::const_string, std::size_t line )
45     {
46         output << line << ": ";
47     }
48
49     void test_unit_finish( std::ostream& output, test_unit const& tu, unsigned long )
50     {
51         output << "Leaving test " << tu.p_type_name << " \"" << tu.p_name << "\"" << std::endl;
52     }
53
54 };
55
56 //____________________________________________________________________________//
57
58 char const* log_level_name[] = {
59     "log_successful_tests",
60     "log_test_suites",
61     "log_messages",
62     "log_warnings",
63     "log_all_errors",
64     "log_cpp_exception_errors",
65     "log_system_errors",
66     "log_fatal_errors",
67     "log_nothing"
68 };
69
70 enum error_type_enum {
71     et_begin,
72     et_none = et_begin,
73     et_message,
74     et_warning,
75     et_user,
76     et_cpp_exception,
77 #ifdef LIMITED_TEST
78     et_fatal_user,
79 #else
80     et_system,
81     et_fatal_user,
82     et_fatal_system,
83 #endif
84     et_end
85 } error_type;
86
87 char const* error_type_name[] = {
88     "no error", "user message", "user warning",
89     "user non-fatal error", "cpp exception", " system error",
90     "user fatal error", "system fatal error"
91 };
92
93 int divide_by_zero = 0;
94
95 void error_on_demand()
96 {
97     switch( error_type ) {
98     case et_none:
99         BOOST_CHECK_MESSAGE( divide_by_zero == 0, "no error" );
100         break;
101
102     case et_message:
103         BOOST_TEST_MESSAGE( "message" );
104         break;
105
106     case et_warning:
107         BOOST_WARN_MESSAGE( divide_by_zero != 0, "warning" );
108         break;
109
110     case et_user:
111         BOOST_ERROR( "non-fatal error" );
112         break;
113
114     case et_fatal_user:
115         BOOST_FAIL( "fatal error" );
116
117         BOOST_ERROR( "Should never reach this code!" );
118         break;
119
120     case et_cpp_exception:
121         BOOST_TEST_CHECKPOINT( "error_on_demand() throw runtime_error" );
122         throw std::runtime_error( "test std::runtime error what() message" );
123
124 #ifndef LIMITED_TEST
125     case et_system:
126         BOOST_TEST_CHECKPOINT( "error_on_demand() divide by zero" );
127         divide_by_zero = 1 / divide_by_zero;
128         break;
129
130     case et_fatal_system:
131         BOOST_TEST_CHECKPOINT( "write to an invalid address" );
132         {
133             int* p = 0;
134             *p = 0;
135
136             BOOST_ERROR( "Should never reach this code!" );
137         }
138         break;
139 #endif
140     default:
141         BOOST_ERROR( "Should never reach this code!" );
142     }
143     return;
144 }
145
146 }  // local namespace
147
148 //____________________________________________________________________________//
149
150 BOOST_AUTO_TEST_CASE( test_errors_handling )
151 {
152 #define PATTERN_FILE_NAME "errors_handling_test.pattern"
153     std::string pattern_file_name(
154         framework::master_test_suite().argc <= 1 
155             ? (runtime_config::save_pattern() ? PATTERN_FILE_NAME : "./test_files/" PATTERN_FILE_NAME)
156             : framework::master_test_suite().argv[1] );
157
158 #ifdef LIMITED_TEST
159     pattern_file_name += "2";
160 #endif
161
162     output_test_stream test_output( pattern_file_name, !runtime_config::save_pattern() );
163
164     test_case* test = BOOST_TEST_CASE( &error_on_demand );
165
166     // for each log level
167     for( log_level level = log_successful_tests;
168          level          <= log_nothing;
169          level           = static_cast<log_level>(level+1) )
170     {
171         // for each error type
172         for( error_type = et_begin;
173              error_type != et_end;
174              error_type = static_cast<error_type_enum>(error_type+1) )
175         {
176             test_output << "\n===========================\n"
177                         << "log level: "       << log_level_name[level] << ';'
178                         << " error type: "     << error_type_name[error_type] << ";\n" << std::endl;
179
180             unit_test_log.set_stream( test_output );
181             unit_test_log.set_formatter( new this_test_log_formatter );
182             unit_test_log.set_threshold_level( level );
183             framework::run( test );
184
185             unit_test_log.set_stream( std::cout );
186             unit_test_log.set_format( runtime_config::log_format() );
187             unit_test_log.set_threshold_level( runtime_config::log_level() != invalid_log_level
188                                                 ? runtime_config::log_level()
189                                                 : log_all_errors );
190             BOOST_CHECK( test_output.match_pattern() );
191         }
192     }
193 }
194
195 //____________________________________________________________________________//
196
197 // EOF
198