diff options
Diffstat (limited to 'boost/test/impl/junit_log_formatter.ipp')
-rw-r--r-- | boost/test/impl/junit_log_formatter.ipp | 274 |
1 files changed, 171 insertions, 103 deletions
diff --git a/boost/test/impl/junit_log_formatter.ipp b/boost/test/impl/junit_log_formatter.ipp index dd528bc903..0ec8d43832 100644 --- a/boost/test/impl/junit_log_formatter.ipp +++ b/boost/test/impl/junit_log_formatter.ipp @@ -69,6 +69,12 @@ inline std::string tu_name_normalize(std::string full_name) return full_name; } +inline std::string tu_name_remove_newlines(std::string full_name) +{ + full_name.erase(std::remove(full_name.begin(), full_name.end(), '\n'), full_name.end()); + return full_name; +} + const_string file_basename(const_string filename) { const_string path_sep( "\\/" ); @@ -86,7 +92,7 @@ const_string file_basename(const_string filename) { // ************************************************************************** // void -junit_log_formatter::log_start( std::ostream& ostr, counter_t test_cases_amount) +junit_log_formatter::log_start( std::ostream& /*ostr*/, counter_t /*test_cases_amount*/) { map_tests.clear(); list_path_to_root.clear(); @@ -96,6 +102,11 @@ junit_log_formatter::log_start( std::ostream& ostr, counter_t test_cases_amount) //____________________________________________________________________________// class junit_result_helper : public test_tree_visitor { +private: + typedef junit_impl::junit_log_helper::assertion_entry assertion_entry; + typedef std::vector< assertion_entry >::const_iterator vect_assertion_entry_citerator; + typedef std::list<std::string>::const_iterator list_str_citerator; + public: explicit junit_result_helper( std::ostream& stream, @@ -111,10 +122,19 @@ public: , m_display_build_info(display_build_info) { } - void add_log_entry(std::string const& entry_type, - test_case const& tc, - junit_impl::junit_log_helper::assertion_entry const& log) const + void add_log_entry(assertion_entry const& log) const { + std::string entry_type; + if( log.log_entry == assertion_entry::log_entry_failure ) { + entry_type = "failure"; + } + else if( log.log_entry == assertion_entry::log_entry_error ) { + entry_type = "error"; + } + else { + return; + } + m_stream << "<" << entry_type << " message" << utils::attr_value() << log.logentry_message @@ -159,24 +179,24 @@ public: } }; - std::list<std::string> build_skipping_chain(test_case const & tc) const + std::list<std::string> build_skipping_chain(test_unit const & tu) const { - // we enter here because we know that the tc has been skipped. - // either junit has not seen this tc, or it is indicated as disabled - assert(m_map_test.count(tc.p_id) == 0 || results_collector.results( tc.p_id ).p_skipped); + // we enter here because we know that the tu has been skipped. + // either junit has not seen this tu, or it is indicated as disabled + assert(m_map_test.count(tu.p_id) == 0 || results_collector.results( tu.p_id ).p_skipped); std::list<std::string> out; - test_unit_id id(tc.p_id); + test_unit_id id(tu.p_id); while( id != m_ts.p_id && id != INV_TEST_UNIT_ID) { - test_unit const& tu = boost::unit_test::framework::get( id, TUT_ANY ); - out.push_back("- disabled test unit: '" + tu.full_name() + "'\n"); + test_unit const& tu_hierarchy = boost::unit_test::framework::get( id, TUT_ANY ); + out.push_back("- disabled test unit: '" + tu_name_remove_newlines(tu_hierarchy.full_name()) + "'\n"); if(m_map_test.count(id) > 0) { // junit has seen the reason: this is enough for constructing the chain break; } - id = tu.p_parent_id; + id = tu_hierarchy.p_parent_id; } junit_log_formatter::map_trace_t::const_iterator it_element_stack(m_map_test.find(id)); if( it_element_stack != m_map_test.end() ) @@ -188,9 +208,9 @@ public: return out; } - std::string get_class_name(test_case const & tc) const { + std::string get_class_name(test_unit const & tu_class) const { std::string classname; - test_unit_id id(tc.p_parent_id); + test_unit_id id(tu_class.p_parent_id); while( id != m_ts.p_id && id != INV_TEST_UNIT_ID ) { test_unit const& tu = boost::unit_test::framework::get( id, TUT_ANY ); classname = tu_name_normalize(tu.p_name) + "." + classname; @@ -205,39 +225,47 @@ public: return classname; } - void write_testcase_header(test_case const & tc, - test_results const *tr = 0) const + void write_testcase_header(test_unit const & tu, + test_results const *tr, + int nb_assertions) const { - // - // test case header + std::string name; + std::string classname; - // total number of assertions - m_stream << "<testcase assertions" << utils::attr_value() << tr->p_assertions_passed + tr->p_assertions_failed; + if(tu.p_id == m_ts.p_id ) { + name = "boost_test"; + } + else { + classname = get_class_name(tu); + name = tu_name_normalize(tu.p_name); + } - // class name - const std::string classname = get_class_name(tc); + if( tu.p_type == TUT_SUITE ) { + name += "-setup-teardown"; + } + + m_stream << "<testcase assertions" << utils::attr_value() << nb_assertions; if(!classname.empty()) m_stream << " classname" << utils::attr_value() << classname; // test case name and time taken m_stream - << " name" << utils::attr_value() << tu_name_normalize(tc.p_name) + << " name" << utils::attr_value() << name << " time" << utils::attr_value() << double(tr->p_duration_microseconds) * 1E-6 << ">" << std::endl; } void write_testcase_system_out(junit_impl::junit_log_helper const &detailed_log, - test_case const * tc, - bool skipped, - test_results const *tr = 0) const + test_unit const * tu, + bool skipped) const { // system-out + all info/messages, the object skips the empty entries conditional_cdata_helper system_out_helper(m_stream, "system-out"); // indicate why the test has been skipped first if( skipped ) { - std::list<std::string> skipping_decision_chain = build_skipping_chain(*tc); - for(std::list<std::string>::const_iterator it(skipping_decision_chain.begin()), ite(skipping_decision_chain.end()); + std::list<std::string> skipping_decision_chain = build_skipping_chain(*tu); + for(list_str_citerator it(skipping_decision_chain.begin()), ite(skipping_decision_chain.end()); it != ite; ++it) { @@ -246,7 +274,7 @@ public: } // stdout - for(std::list<std::string>::const_iterator it(detailed_log.system_out.begin()), ite(detailed_log.system_out.end()); + for(list_str_citerator it(detailed_log.system_out.begin()), ite(detailed_log.system_out.end()); it != ite; ++it) { @@ -254,25 +282,24 @@ public: } // warning/info message last - for(std::vector< junit_impl::junit_log_helper::assertion_entry >::const_iterator it(detailed_log.assertion_entries.begin()); + for(vect_assertion_entry_citerator it(detailed_log.assertion_entries.begin()); it != detailed_log.assertion_entries.end(); ++it) { - if(it->log_entry != junit_impl::junit_log_helper::assertion_entry::log_entry_info) + if(it->log_entry != assertion_entry::log_entry_info) continue; system_out_helper(it->output); } } void write_testcase_system_err(junit_impl::junit_log_helper const &detailed_log, - test_case const * tc, - test_results const *tr = 0) const + test_unit const * tu, + test_results const *tr) const { // system-err output + test case informations - bool has_failed = (tr != 0) ? !tr->passed() : false; + bool has_failed = (tr != 0) ? !tr->p_skipped && !tr->passed() : false; if(!detailed_log.system_err.empty() || has_failed) { - conditional_cdata_helper system_err_helper(m_stream, "system-err"); std::ostringstream o; if(has_failed) { o << "Failures detected in:" << std::endl; @@ -281,58 +308,89 @@ public: o << "ERROR STREAM:" << std::endl; } - o << "- test case: " << tc->full_name() << std::endl; - if(!tc->p_description.value.empty()) - o << " '" << tc->p_description << "'"; - - o << std::endl - << "- file: " << file_basename(tc->p_file_name) << std::endl - << "- line: " << tc->p_line_num << std::endl - ; + if(tu->p_type == TUT_SUITE) { + if( tu->p_id == m_ts.p_id ) { + o << " boost.test global setup/teardown" << std::endl; + } else { + o << "- test suite: " << tu_name_remove_newlines(tu->full_name()) << std::endl; + } + } + else { + o << "- test case: " << tu_name_remove_newlines(tu->full_name()); + if(!tu->p_description.value.empty()) + o << " '" << tu->p_description << "'"; + + o << std::endl + << "- file: " << file_basename(tu->p_file_name) << std::endl + << "- line: " << tu->p_line_num << std::endl + ; + } if(!detailed_log.system_err.empty()) o << std::endl << "STDERR BEGIN: ------------" << std::endl; - system_err_helper(o.str()); - for(std::list<std::string>::const_iterator it(detailed_log.system_err.begin()), ite(detailed_log.system_err.end()); + for(list_str_citerator it(detailed_log.system_err.begin()), ite(detailed_log.system_err.end()); it != ite; ++it) { - system_err_helper(*it); + o << *it; } if(!detailed_log.system_err.empty()) o << std::endl << "STDERR END ------------" << std::endl; + + conditional_cdata_helper system_err_helper(m_stream, "system-err"); + system_err_helper(o.str()); + } + } + + int get_nb_assertions(junit_impl::junit_log_helper const &detailed_log, + test_unit const & tu, + test_results const *tr) const { + int nb_assertions(-1); + if( tu.p_type == TUT_SUITE ) { + nb_assertions = 0; + for(vect_assertion_entry_citerator it(detailed_log.assertion_entries.begin()); + it != detailed_log.assertion_entries.end(); + ++it) + { + if(it->log_entry != assertion_entry::log_entry_info) + nb_assertions++; + } + } + else { + nb_assertions = tr->p_assertions_passed + tr->p_assertions_failed; } + + return nb_assertions; } void output_detailed_logs(junit_impl::junit_log_helper const &detailed_log, - test_case const & tc, + test_unit const & tu, bool skipped, - test_results const *tr = 0) const + test_results const *tr) const { - write_testcase_header(tc, tr); + int nb_assertions = get_nb_assertions(detailed_log, tu, tr); + if(!nb_assertions && tu.p_type == TUT_SUITE) + return; + + write_testcase_header(tu, tr, nb_assertions); if( skipped ) { m_stream << "<skipped/>" << std::endl; } else { - for(std::vector< junit_impl::junit_log_helper::assertion_entry >::const_iterator it(detailed_log.assertion_entries.begin()); + for(vect_assertion_entry_citerator it(detailed_log.assertion_entries.begin()); it != detailed_log.assertion_entries.end(); ++it) { - if(it->log_entry == junit_impl::junit_log_helper::assertion_entry::log_entry_failure) { - add_log_entry("failure", tc, *it); - } - else if(it->log_entry == junit_impl::junit_log_helper::assertion_entry::log_entry_error) { - add_log_entry("error", tc, *it); - } + add_log_entry(*it); } } - write_testcase_system_out(detailed_log, &tc, skipped, tr); - write_testcase_system_err(detailed_log, &tc, tr); + write_testcase_system_out(detailed_log, &tu, skipped); + write_testcase_system_err(detailed_log, &tu, tr); m_stream << "</testcase>" << std::endl; } @@ -353,35 +411,45 @@ public: bool test_suite_start( test_suite const& ts ) { - // unique test suite, without s, nesting not supported in CI - if( m_ts.p_id != ts.p_id ) - return true; - test_results const& tr = results_collector.results( ts.p_id ); - m_stream << "<testsuite"; - m_stream - // << "disabled=\"" << tr.p_test_cases_skipped << "\" " - << " tests" << utils::attr_value() << tr.p_test_cases_passed - << " skipped" << utils::attr_value() << tr.p_test_cases_skipped - << " errors" << utils::attr_value() << tr.p_test_cases_aborted - << " failures" << utils::attr_value() << tr.p_test_cases_failed - << " id" << utils::attr_value() << m_id++ - << " name" << utils::attr_value() << tu_name_normalize(ts.p_name) - << " time" << utils::attr_value() << (tr.p_duration_microseconds * 1E-6) - << ">" << std::endl; - - if(m_display_build_info) - { - m_stream << "<properties>" << std::endl; - m_stream << "<property name=\"platform\" value" << utils::attr_value() << BOOST_PLATFORM << std::endl; - m_stream << "<property name=\"compiler\" value" << utils::attr_value() << BOOST_COMPILER << std::endl; - m_stream << "<property name=\"stl\" value" << utils::attr_value() << BOOST_STDLIB << std::endl; + // unique test suite, without s, nesting not supported in CI + if( m_ts.p_id == ts.p_id ) { + m_stream << "<testsuite"; + + m_stream + // << "disabled=\"" << tr.p_test_cases_skipped << "\" " + << " tests" << utils::attr_value() << tr.p_test_cases_passed + << " skipped" << utils::attr_value() << tr.p_test_cases_skipped + << " errors" << utils::attr_value() << tr.p_test_cases_aborted + << " failures" << utils::attr_value() << tr.p_test_cases_failed + << " id" << utils::attr_value() << m_id++ + << " name" << utils::attr_value() << tu_name_normalize(ts.p_name) + << " time" << utils::attr_value() << (tr.p_duration_microseconds * 1E-6) + << ">" << std::endl; + + if(m_display_build_info) + { + m_stream << "<properties>" << std::endl; + m_stream << "<property name=\"platform\" value" << utils::attr_value() << BOOST_PLATFORM << std::endl; + m_stream << "<property name=\"compiler\" value" << utils::attr_value() << BOOST_COMPILER << std::endl; + m_stream << "<property name=\"stl\" value" << utils::attr_value() << BOOST_STDLIB << std::endl; + + std::ostringstream o; + o << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100; + m_stream << "<property name=\"boost\" value" << utils::attr_value() << o.str() << std::endl; + m_stream << "</properties>" << std::endl; + } + } - std::ostringstream o; - o << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100; - m_stream << "<property name=\"boost\" value" << utils::attr_value() << o.str() << std::endl; - m_stream << "</properties>" << std::endl; + if( !tr.p_skipped ) { + // if we land here, then this is a chance that we are logging the fixture setup/teardown of a test-suite. + // the setup/teardown logging of a test-case is part of the test case. + // we do not care about the test-suite that were skipped (really??) + junit_log_formatter::map_trace_t::const_iterator it_find = m_map_test.find(ts.p_id); + if(it_find != m_map_test.end()) { + output_detailed_logs(it_find->second, ts, false, &tr); + } } return true; // indicates that the children should also be parsed @@ -389,13 +457,13 @@ public: virtual void test_suite_finish( test_suite const& ts ) { - if( m_ts.p_id != ts.p_id ) - return; + if( m_ts.p_id == ts.p_id ) { + write_testcase_system_out(runner_log, 0, false); + write_testcase_system_err(runner_log, 0, 0); - write_testcase_system_out(runner_log, 0, false, 0); - write_testcase_system_err(runner_log, 0, 0); - - m_stream << "</testsuite>"; + m_stream << "</testsuite>"; + return; + } } private: @@ -439,7 +507,7 @@ junit_log_formatter::log_finish( std::ostream& ostr ) //____________________________________________________________________________// void -junit_log_formatter::log_build_info( std::ostream& ostr ) +junit_log_formatter::log_build_info( std::ostream& /*ostr*/ ) { m_display_build_info = true; } @@ -447,7 +515,7 @@ junit_log_formatter::log_build_info( std::ostream& ostr ) //____________________________________________________________________________// void -junit_log_formatter::test_unit_start( std::ostream& ostr, test_unit const& tu ) +junit_log_formatter::test_unit_start( std::ostream& /*ostr*/, test_unit const& tu ) { list_path_to_root.push_back( tu.p_id ); map_tests.insert(std::make_pair(tu.p_id, junit_impl::junit_log_helper())); // current_test_case_id not working here @@ -458,7 +526,7 @@ junit_log_formatter::test_unit_start( std::ostream& ostr, test_unit const& tu ) //____________________________________________________________________________// void -junit_log_formatter::test_unit_finish( std::ostream& ostr, test_unit const& tu, unsigned long elapsed ) +junit_log_formatter::test_unit_finish( std::ostream& /*ostr*/, test_unit const& tu, unsigned long /*elapsed*/ ) { // the time is already stored in the result_reporter assert( tu.p_id == list_path_to_root.back() ); @@ -466,7 +534,7 @@ junit_log_formatter::test_unit_finish( std::ostream& ostr, test_unit const& tu, } void -junit_log_formatter::test_unit_aborted( std::ostream& os, test_unit const& tu ) +junit_log_formatter::test_unit_aborted( std::ostream& /*ostr*/, test_unit const& tu ) { assert( tu.p_id == list_path_to_root.back() ); //list_path_to_root.pop_back(); @@ -475,7 +543,7 @@ junit_log_formatter::test_unit_aborted( std::ostream& os, test_unit const& tu ) //____________________________________________________________________________// void -junit_log_formatter::test_unit_skipped( std::ostream& ostr, test_unit const& tu, const_string reason ) +junit_log_formatter::test_unit_skipped( std::ostream& /*ostr*/, test_unit const& tu, const_string reason ) { // if a test unit is skipped, then the start of this TU has not been called yet. // we cannot use get_current_log_entry here, but the TU id should appear in the map. @@ -487,7 +555,7 @@ junit_log_formatter::test_unit_skipped( std::ostream& ostr, test_unit const& tu, //____________________________________________________________________________// void -junit_log_formatter::log_exception_start( std::ostream& ostr, log_checkpoint_data const& checkpoint_data, execution_exception const& ex ) +junit_log_formatter::log_exception_start( std::ostream& /*ostr*/, log_checkpoint_data const& checkpoint_data, execution_exception const& ex ) { std::ostringstream o; execution_exception::location const& loc = ex.where(); @@ -555,7 +623,7 @@ junit_log_formatter::log_exception_start( std::ostream& ostr, log_checkpoint_dat //____________________________________________________________________________// void -junit_log_formatter::log_exception_finish( std::ostream& ostr ) +junit_log_formatter::log_exception_finish( std::ostream& /*ostr*/ ) { // sealing the last entry assert(!get_current_log_entry().assertion_entries.back().sealed); @@ -565,7 +633,7 @@ junit_log_formatter::log_exception_finish( std::ostream& ostr ) //____________________________________________________________________________// void -junit_log_formatter::log_entry_start( std::ostream& ostr, log_entry_data const& entry_data, log_entry_types let ) +junit_log_formatter::log_entry_start( std::ostream& /*ostr*/, log_entry_data const& entry_data, log_entry_types let ) { junit_impl::junit_log_helper& last_entry = get_current_log_entry(); last_entry.skipping = false; @@ -638,7 +706,7 @@ junit_log_formatter::log_entry_start( std::ostream& ostr, log_entry_data const& //____________________________________________________________________________// void -junit_log_formatter::log_entry_value( std::ostream& ostr, const_string value ) +junit_log_formatter::log_entry_value( std::ostream& /*ostr*/, const_string value ) { junit_impl::junit_log_helper& last_entry = get_current_log_entry(); if(last_entry.skipping) @@ -662,7 +730,7 @@ junit_log_formatter::log_entry_value( std::ostream& ostr, const_string value ) //____________________________________________________________________________// void -junit_log_formatter::log_entry_finish( std::ostream& ostr ) +junit_log_formatter::log_entry_finish( std::ostream& /*ostr*/ ) { junit_impl::junit_log_helper& last_entry = get_current_log_entry(); if(!last_entry.skipping) @@ -685,7 +753,7 @@ junit_log_formatter::log_entry_finish( std::ostream& ostr ) //____________________________________________________________________________// void -junit_log_formatter::entry_context_start( std::ostream& ostr, log_level ) +junit_log_formatter::entry_context_start( std::ostream& /*ostr*/, log_level ) { junit_impl::junit_log_helper& last_entry = get_current_log_entry(); if(last_entry.skipping) @@ -708,7 +776,7 @@ junit_log_formatter::entry_context_start( std::ostream& ostr, log_level ) //____________________________________________________________________________// void -junit_log_formatter::entry_context_finish( std::ostream& ostr ) +junit_log_formatter::entry_context_finish( std::ostream& /*ostr*/, log_level ) { // no op, may be removed junit_impl::junit_log_helper& last_entry = get_current_log_entry(); @@ -720,7 +788,7 @@ junit_log_formatter::entry_context_finish( std::ostream& ostr ) //____________________________________________________________________________// void -junit_log_formatter::log_entry_context( std::ostream& ostr, const_string context_descr ) +junit_log_formatter::log_entry_context( std::ostream& /*ostr*/, log_level , const_string context_descr ) { junit_impl::junit_log_helper& last_entry = get_current_log_entry(); if(last_entry.skipping) |