summaryrefslogtreecommitdiff
path: root/boost/test/impl/junit_log_formatter.ipp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/test/impl/junit_log_formatter.ipp')
-rw-r--r--boost/test/impl/junit_log_formatter.ipp274
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)