Line data Source code
1 : // (C) Copyright Gennadiy Rozental 2001. 2 : // Distributed under the Boost Software License, Version 1.0. 3 : // (See accompanying file LICENSE_1_0.txt or copy at 4 : // http://www.boost.org/LICENSE_1_0.txt) 5 : 6 : // See http://www.boost.org/libs/test for the library home page. 7 : // 8 : /// @file 9 : /// Test results collecting facility. 10 : /// 11 : // *************************************************************************** 12 : 13 : #ifndef BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER 14 : #define BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER 15 : 16 : // Boost.Test 17 : #include <boost/test/unit_test_log.hpp> 18 : #include <boost/test/results_collector.hpp> 19 : #include <boost/test/framework.hpp> 20 : #include <boost/test/execution_monitor.hpp> 21 : 22 : #include <boost/test/tree/test_unit.hpp> 23 : #include <boost/test/tree/visitor.hpp> 24 : #include <boost/test/tree/test_case_counter.hpp> 25 : #include <boost/test/tree/traverse.hpp> 26 : 27 : // Boost 28 : #include <boost/cstdlib.hpp> 29 : 30 : // STL 31 : #include <map> 32 : 33 : #include <boost/test/detail/suppress_warnings.hpp> 34 : 35 : //____________________________________________________________________________// 36 : 37 : namespace boost { 38 : namespace unit_test { 39 : 40 : // ************************************************************************** // 41 : // ************** test_results ************** // 42 : // ************************************************************************** // 43 : 44 44050 : test_results::test_results() 45 22025 : { 46 22025 : clear(); 47 44050 : } 48 : 49 : //____________________________________________________________________________// 50 : 51 : bool 52 987 : test_results::passed() const 53 : { 54 : // if it is skipped, it is not passed. However, if any children is not failed/aborted 55 : // then their skipped status is not taken into account. 56 1974 : return !p_skipped && 57 987 : p_test_cases_failed == 0 && 58 987 : p_assertions_failed <= p_expected_failures && 59 : // p_test_cases_skipped == 0 && 60 987 : !p_timed_out && 61 987 : p_test_cases_timed_out == 0 && 62 987 : !aborted(); 63 : } 64 : 65 : //____________________________________________________________________________// 66 : 67 : bool 68 987 : test_results::aborted() const 69 : { 70 987 : return p_aborted; 71 : } 72 : 73 : //____________________________________________________________________________// 74 : 75 : bool 76 0 : test_results::skipped() const 77 : { 78 0 : return p_skipped; 79 : } 80 : 81 : //____________________________________________________________________________// 82 : 83 : int 84 145 : test_results::result_code() const 85 : { 86 145 : return passed() ? exit_success 87 0 : : ( (p_assertions_failed > p_expected_failures || p_skipped || p_timed_out || p_test_cases_timed_out ) 88 : ? exit_test_failure 89 : : exit_exception_failure ); 90 : } 91 : 92 : //____________________________________________________________________________// 93 : 94 : void 95 21722 : test_results::operator+=( test_results const& tr ) 96 : { 97 21722 : p_test_suites.value += tr.p_test_suites; 98 21722 : p_assertions_passed.value += tr.p_assertions_passed; 99 21722 : p_assertions_failed.value += tr.p_assertions_failed; 100 21722 : p_warnings_failed.value += tr.p_warnings_failed; 101 21722 : p_test_cases_passed.value += tr.p_test_cases_passed; 102 21722 : p_test_cases_warned.value += tr.p_test_cases_warned; 103 21722 : p_test_cases_failed.value += tr.p_test_cases_failed; 104 21722 : p_test_cases_skipped.value += tr.p_test_cases_skipped; 105 21722 : p_test_cases_aborted.value += tr.p_test_cases_aborted; 106 21722 : p_test_cases_timed_out.value += tr.p_test_cases_timed_out; 107 21722 : p_test_suites_timed_out.value += tr.p_test_suites_timed_out; 108 21722 : p_duration_microseconds.value += tr.p_duration_microseconds; 109 21722 : } 110 : 111 : //____________________________________________________________________________// 112 : 113 : void 114 44050 : test_results::clear() 115 : { 116 44050 : p_test_suites.value = 0; 117 44050 : p_assertions_passed.value = 0; 118 44050 : p_assertions_failed.value = 0; 119 44050 : p_warnings_failed.value = 0; 120 44050 : p_expected_failures.value = 0; 121 44050 : p_test_cases_passed.value = 0; 122 44050 : p_test_cases_warned.value = 0; 123 44050 : p_test_cases_failed.value = 0; 124 44050 : p_test_cases_skipped.value = 0; 125 44050 : p_test_cases_aborted.value = 0; 126 44050 : p_test_cases_timed_out.value = 0; 127 44050 : p_test_suites_timed_out.value = 0; 128 44050 : p_duration_microseconds.value= 0; 129 44050 : p_aborted.value = false; 130 44050 : p_skipped.value = false; 131 44050 : p_timed_out.value = false; 132 44050 : } 133 : 134 : //____________________________________________________________________________// 135 : 136 : // ************************************************************************** // 137 : // ************** results_collector ************** // 138 : // ************************************************************************** // 139 : 140 : namespace { 141 : 142 : struct results_collector_impl { 143 : std::map<test_unit_id,test_results> m_results_store; 144 : }; 145 : 146 8882887 : results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; return the_inst; } 147 : 148 : // deletes the entries of results_collector_impl 149 : class clear_subtree_result : public test_tree_visitor { 150 : public: 151 292 : clear_subtree_result(results_collector_impl& store) 152 146 : : m_store( store ) 153 438 : {} 154 : 155 : private: 156 1041 : bool visit( test_unit const& tu) BOOST_OVERRIDE 157 : { 158 : typedef std::map<test_unit_id,test_results>::iterator iterator; 159 1041 : iterator found = m_store.m_results_store.find(tu.p_id); 160 1041 : if(found != m_store.m_results_store.end()) { 161 0 : m_store.m_results_store.erase( found ); 162 0 : } 163 1041 : return true; 164 : } 165 : 166 : results_collector_impl& m_store; 167 : }; 168 : 169 : } // local namespace 170 : 171 : //____________________________________________________________________________// 172 : 173 146 : BOOST_TEST_SINGLETON_CONS_IMPL( results_collector_t ) 174 : 175 : //____________________________________________________________________________// 176 : 177 : void 178 146 : results_collector_t::test_start( counter_t, test_unit_id id ) 179 : { 180 : // deletes the results under id only 181 146 : clear_subtree_result tree_clear(s_rc_impl()); 182 146 : traverse_test_tree( id, tree_clear ); 183 146 : } 184 : 185 : //____________________________________________________________________________// 186 : 187 : void 188 1023 : results_collector_t::test_unit_start( test_unit const& tu ) 189 : { 190 : // init test_results entry 191 1023 : test_results& tr = s_rc_impl().m_results_store[tu.p_id]; 192 : 193 1023 : tr.clear(); 194 : 195 1023 : tr.p_expected_failures.value = tu.p_expected_failures; 196 1023 : } 197 : 198 : //____________________________________________________________________________// 199 : 200 : class results_collect_helper : public test_tree_visitor { 201 : public: 202 580 : explicit results_collect_helper( test_results& tr, test_unit const& ts ) : m_tr( tr ), m_ts( ts ) {} 203 : 204 697 : void visit( test_case const& tc ) BOOST_OVERRIDE 205 : { 206 697 : test_results const& tr = results_collector.results( tc.p_id ); 207 697 : m_tr += tr; 208 : 209 697 : if( tr.passed() ) { 210 697 : if( tr.p_warnings_failed ) 211 0 : m_tr.p_test_cases_warned.value++; 212 : else 213 697 : m_tr.p_test_cases_passed.value++; 214 697 : } 215 0 : else if( tr.p_timed_out ) { 216 0 : m_tr.p_test_cases_timed_out.value++; 217 0 : } 218 0 : else if( tr.p_skipped || !tc.is_enabled() ) { 219 0 : m_tr.p_test_cases_skipped.value++; 220 0 : } 221 : else { 222 0 : if( tr.p_aborted ) 223 0 : m_tr.p_test_cases_aborted.value++; 224 : 225 0 : m_tr.p_test_cases_failed.value++; 226 : } 227 697 : } 228 21315 : bool test_suite_start( test_suite const& ts ) BOOST_OVERRIDE 229 : { 230 21315 : if( m_ts.p_id == ts.p_id ) 231 290 : return true; 232 : 233 21025 : m_tr += results_collector.results( ts.p_id ); 234 21025 : m_tr.p_test_suites.value++; 235 : 236 21025 : if( results_collector.results( ts.p_id ).p_timed_out ) 237 0 : m_tr.p_test_suites_timed_out.value++; 238 21025 : return false; 239 21315 : } 240 : 241 : private: 242 : // Data members 243 : test_results& m_tr; 244 : test_unit const& m_ts; 245 : }; 246 : 247 : //____________________________________________________________________________// 248 : 249 : void 250 1020 : results_collector_t::test_unit_finish( test_unit const& tu, unsigned long elapsed_in_microseconds ) 251 : { 252 1020 : test_results & tr = s_rc_impl().m_results_store[tu.p_id]; 253 1020 : if( tu.p_type == TUT_SUITE ) { 254 290 : results_collect_helper ch( tr, tu ); 255 290 : traverse_test_tree( tu, ch, true ); // true to ignore the status: we need to count the skipped/disabled tests 256 290 : } 257 : else { 258 730 : bool num_failures_match = tr.p_aborted || tr.p_assertions_failed >= tr.p_expected_failures; 259 730 : if( !num_failures_match ) 260 0 : BOOST_TEST_FRAMEWORK_MESSAGE( "Test case " << tu.full_name() << " has fewer failures than expected" ); 261 : 262 730 : bool check_any_assertions = tr.p_aborted || (tr.p_assertions_failed != 0) || (tr.p_assertions_passed != 0); 263 730 : if( !check_any_assertions ) 264 3 : BOOST_TEST_FRAMEWORK_MESSAGE( "Test case " << tu.full_name() << " did not check any assertions" ); 265 : } 266 1020 : tr.p_duration_microseconds.value = elapsed_in_microseconds; 267 1020 : } 268 : 269 : //____________________________________________________________________________// 270 : 271 : void 272 21002 : results_collector_t::test_unit_skipped( test_unit const& tu, const_string /*reason*/ ) 273 : { 274 21002 : test_results& tr = s_rc_impl().m_results_store[tu.p_id]; 275 21002 : tr.clear(); 276 : 277 21002 : tr.p_skipped.value = true; 278 : 279 21002 : if( tu.p_type == TUT_SUITE ) { 280 21002 : test_case_counter tcc(true); 281 21002 : traverse_test_tree( tu, tcc, true ); // true because need to count the disabled tests/units 282 : 283 21002 : tr.p_test_cases_skipped.value = tcc.p_count; 284 21002 : } 285 21002 : } 286 : 287 : //____________________________________________________________________________// 288 : 289 : void 290 0 : results_collector_t::test_unit_timed_out(test_unit const& tu) 291 : { 292 0 : test_results& tr = s_rc_impl().m_results_store[tu.p_id]; 293 0 : tr.p_timed_out.value = true; 294 0 : } 295 : 296 : //____________________________________________________________________________// 297 : 298 : void 299 8816659 : results_collector_t::assertion_result( unit_test::assertion_result ar ) 300 : { 301 8816659 : test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()]; 302 : 303 8816659 : switch( ar ) { 304 8816659 : case AR_PASSED: tr.p_assertions_passed.value++; break; 305 0 : case AR_FAILED: tr.p_assertions_failed.value++; break; 306 0 : case AR_TRIGGERED: tr.p_warnings_failed.value++; break; 307 : } 308 : 309 8816659 : if( tr.p_assertions_failed == 1 ) 310 0 : first_failed_assertion(); 311 8816659 : } 312 : 313 : //____________________________________________________________________________// 314 : 315 : void 316 0 : results_collector_t::exception_caught( execution_exception const& ex) 317 : { 318 0 : test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()]; 319 : 320 0 : tr.p_assertions_failed.value++; 321 0 : if( ex.code() == execution_exception::timeout_error ) { 322 0 : tr.p_timed_out.value = true; 323 0 : } 324 0 : } 325 : 326 : //____________________________________________________________________________// 327 : 328 : void 329 0 : results_collector_t::test_unit_aborted( test_unit const& tu ) 330 : { 331 0 : s_rc_impl().m_results_store[tu.p_id].p_aborted.value = true; 332 0 : } 333 : 334 : //____________________________________________________________________________// 335 : 336 : test_results const& 337 43037 : results_collector_t::results( test_unit_id id ) const 338 : { 339 43037 : return s_rc_impl().m_results_store[id]; 340 : } 341 : 342 : //____________________________________________________________________________// 343 : 344 : } // namespace unit_test 345 : } // namespace boost 346 : 347 : #include <boost/test/detail/enable_warnings.hpp> 348 : 349 : #endif // BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER