update boost on linux
This commit is contained in:
@@ -52,7 +52,7 @@ namespace {
|
||||
std::string
|
||||
test_phase_identifier()
|
||||
{
|
||||
return framework::test_in_progress() ? framework::current_test_case().full_name() : std::string( "Test setup" );
|
||||
return framework::test_in_progress() ? framework::current_test_unit().full_name() : std::string( "Test setup" );
|
||||
}
|
||||
|
||||
} // local namespace
|
||||
@@ -80,14 +80,16 @@ compiler_log_formatter::log_finish( std::ostream& ostr )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
compiler_log_formatter::log_build_info( std::ostream& output )
|
||||
compiler_log_formatter::log_build_info( std::ostream& output, bool log_build_info )
|
||||
{
|
||||
output << "Platform: " << BOOST_PLATFORM << '\n'
|
||||
<< "Compiler: " << BOOST_COMPILER << '\n'
|
||||
<< "STL : " << BOOST_STDLIB << '\n'
|
||||
<< "Boost : " << BOOST_VERSION/100000 << "."
|
||||
<< BOOST_VERSION/100 % 1000 << "."
|
||||
<< BOOST_VERSION % 100 << std::endl;
|
||||
if(log_build_info) {
|
||||
output << "Platform: " << BOOST_PLATFORM << '\n'
|
||||
<< "Compiler: " << BOOST_COMPILER << '\n'
|
||||
<< "STL : " << BOOST_STDLIB << '\n'
|
||||
<< "Boost : " << BOOST_VERSION/100000 << "."
|
||||
<< BOOST_VERSION/100 % 1000 << "."
|
||||
<< BOOST_VERSION % 100 << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -182,30 +184,25 @@ compiler_log_formatter::log_entry_start( std::ostream& output, log_entry_data co
|
||||
switch( let ) {
|
||||
case BOOST_UTL_ET_INFO:
|
||||
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
|
||||
if( m_color_output )
|
||||
output << setcolor( term_attr::BRIGHT, term_color::GREEN );
|
||||
output << setcolor( m_color_output, term_attr::BRIGHT, term_color::GREEN );
|
||||
output << "info: ";
|
||||
break;
|
||||
case BOOST_UTL_ET_MESSAGE:
|
||||
if( m_color_output )
|
||||
output << setcolor( term_attr::BRIGHT, term_color::CYAN );
|
||||
output << setcolor( m_color_output, term_attr::BRIGHT, term_color::CYAN );
|
||||
break;
|
||||
case BOOST_UTL_ET_WARNING:
|
||||
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
|
||||
if( m_color_output )
|
||||
output << setcolor( term_attr::BRIGHT, term_color::YELLOW );
|
||||
output << setcolor( m_color_output, term_attr::BRIGHT, term_color::YELLOW );
|
||||
output << "warning: in \"" << test_phase_identifier() << "\": ";
|
||||
break;
|
||||
case BOOST_UTL_ET_ERROR:
|
||||
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
|
||||
if( m_color_output )
|
||||
output << setcolor( term_attr::BRIGHT, term_color::RED );
|
||||
output << setcolor( m_color_output, term_attr::BRIGHT, term_color::RED );
|
||||
output << "error: in \"" << test_phase_identifier() << "\": ";
|
||||
break;
|
||||
case BOOST_UTL_ET_FATAL_ERROR:
|
||||
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
|
||||
if( m_color_output )
|
||||
output << setcolor( term_attr::UNDERLINE, term_color::RED );
|
||||
output << setcolor( m_color_output, term_attr::UNDERLINE, term_color::RED );
|
||||
output << "fatal error: in \"" << test_phase_identifier() << "\": ";
|
||||
break;
|
||||
}
|
||||
@@ -233,7 +230,7 @@ void
|
||||
compiler_log_formatter::log_entry_finish( std::ostream& output )
|
||||
{
|
||||
if( m_color_output )
|
||||
output << utils::setcolor();
|
||||
output << utils::setcolor(m_color_output);
|
||||
|
||||
output << std::endl;
|
||||
}
|
||||
@@ -260,21 +257,29 @@ compiler_log_formatter::print_prefix( std::ostream& output, const_string file_na
|
||||
void
|
||||
compiler_log_formatter::entry_context_start( std::ostream& output, log_level l )
|
||||
{
|
||||
output << (l == log_successful_tests ? "\nAssertion" : "\nFailure" ) << " occurred in a following context:";
|
||||
if( l == log_messages ) {
|
||||
output << "\n[context:";
|
||||
}
|
||||
else {
|
||||
output << (l == log_successful_tests ? "\nAssertion" : "\nFailure" ) << " occurred in a following context:";
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
compiler_log_formatter::entry_context_finish( std::ostream& output )
|
||||
compiler_log_formatter::entry_context_finish( std::ostream& output, log_level l )
|
||||
{
|
||||
if( l == log_messages ) {
|
||||
output << "]";
|
||||
}
|
||||
output.flush();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
compiler_log_formatter::log_entry_context( std::ostream& output, const_string context_descr )
|
||||
compiler_log_formatter::log_entry_context( std::ostream& output, log_level /*l*/, const_string context_descr )
|
||||
{
|
||||
output << "\n " << context_descr;
|
||||
}
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/detail/config.hpp>
|
||||
#include <boost/test/detail/workaround.hpp>
|
||||
#include <boost/test/detail/global_typedef.hpp>
|
||||
|
||||
#include <boost/test/debug.hpp>
|
||||
#include <boost/test/debug_config.hpp>
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
// Implementation on Windows
|
||||
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(BOOST_DISABLE_WIN32) // ******* WIN32
|
||||
|
||||
@@ -768,7 +769,7 @@ struct safe_handle_helper
|
||||
}
|
||||
}
|
||||
|
||||
~safe_handle_helper()
|
||||
~safe_handle_helper()
|
||||
{
|
||||
close_handle();
|
||||
}
|
||||
@@ -804,7 +805,7 @@ attach_debugger( bool break_or_continue )
|
||||
|
||||
if( !dbg_init_done_ev )
|
||||
return false;
|
||||
|
||||
|
||||
safe_handle_helper safe_handle_obj( dbg_init_done_ev );
|
||||
|
||||
// *************************************************** //
|
||||
@@ -822,7 +823,7 @@ attach_debugger( bool break_or_continue )
|
||||
DWORD format_size = MAX_CMD_LINE;
|
||||
DWORD type = REG_SZ;
|
||||
|
||||
bool b_read_key = s_info.m_reg_query_value &&
|
||||
bool b_read_key = s_info.m_reg_query_value &&
|
||||
((*s_info.m_reg_query_value)(
|
||||
reg_key, // handle of open key
|
||||
"Debugger", // name of subkey to query
|
||||
@@ -833,7 +834,7 @@ attach_debugger( bool break_or_continue )
|
||||
|
||||
if( !s_info.m_reg_close_key || (*s_info.m_reg_close_key)( reg_key ) != ERROR_SUCCESS )
|
||||
return false;
|
||||
|
||||
|
||||
if( !b_read_key )
|
||||
return false;
|
||||
|
||||
@@ -938,7 +939,7 @@ attach_debugger( bool break_or_continue )
|
||||
return true;
|
||||
|
||||
#else // ****************************************************** default
|
||||
|
||||
(void) break_or_continue; // silence 'unused variable' warning
|
||||
return false;
|
||||
|
||||
#endif
|
||||
@@ -953,7 +954,7 @@ attach_debugger( bool break_or_continue )
|
||||
void
|
||||
detect_memory_leaks( bool on_off, unit_test::const_string report_file )
|
||||
{
|
||||
unit_test::ut_detail::ignore_unused_variable_warning( on_off );
|
||||
boost::ignore_unused( on_off );
|
||||
|
||||
#ifdef BOOST_MS_CRT_BASED_DEBUG
|
||||
int flags = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
|
||||
@@ -975,7 +976,7 @@ detect_memory_leaks( bool on_off, unit_test::const_string report_file )
|
||||
|
||||
_CrtSetDbgFlag ( flags );
|
||||
#else
|
||||
unit_test::ut_detail::ignore_unused_variable_warning( report_file );
|
||||
boost::ignore_unused( report_file );
|
||||
#endif // BOOST_MS_CRT_BASED_DEBUG
|
||||
}
|
||||
|
||||
@@ -989,7 +990,7 @@ detect_memory_leaks( bool on_off, unit_test::const_string report_file )
|
||||
void
|
||||
break_memory_alloc( long mem_alloc_order_num )
|
||||
{
|
||||
unit_test::ut_detail::ignore_unused_variable_warning( mem_alloc_order_num );
|
||||
boost::ignore_unused( mem_alloc_order_num );
|
||||
|
||||
#ifdef BOOST_MS_CRT_BASED_DEBUG
|
||||
// only set the value if one was supplied (do not use default used by UTF just as a indicator to enable leak detection)
|
||||
@@ -1006,4 +1007,3 @@ break_memory_alloc( long mem_alloc_order_num )
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DEBUG_API_IPP_112006GER
|
||||
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
// File : $RCSfile$
|
||||
//
|
||||
// Version : $Revision$
|
||||
//
|
||||
// Description : unit test decorators implementation
|
||||
// ***************************************************************************
|
||||
|
||||
@@ -35,13 +31,17 @@ namespace unit_test {
|
||||
namespace decorator {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** decorator::collector ************** //
|
||||
// ************** decorator::collector_t ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
collector&
|
||||
collector::operator*( base const& d )
|
||||
// singleton pattern
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL(collector_t)
|
||||
|
||||
|
||||
collector_t&
|
||||
collector_t::operator*( base const& d )
|
||||
{
|
||||
m_tu_decorators.push_back( d.clone() );
|
||||
m_tu_decorators_stack.begin()->push_back( d.clone() );
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -49,17 +49,41 @@ collector::operator*( base const& d )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
collector::store_in( test_unit& tu )
|
||||
collector_t::store_in( test_unit& tu )
|
||||
{
|
||||
tu.p_decorators.value.insert( tu.p_decorators.value.end(), m_tu_decorators.begin(), m_tu_decorators.end() );
|
||||
tu.p_decorators.value.insert(
|
||||
tu.p_decorators.value.end(),
|
||||
m_tu_decorators_stack.begin()->begin(),
|
||||
m_tu_decorators_stack.begin()->end() );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
collector::reset()
|
||||
collector_t::reset()
|
||||
{
|
||||
m_tu_decorators.clear();
|
||||
if(m_tu_decorators_stack.size() > 1) {
|
||||
m_tu_decorators_stack.erase(m_tu_decorators_stack.begin());
|
||||
}
|
||||
else {
|
||||
assert(m_tu_decorators_stack.size() == 1);
|
||||
m_tu_decorators_stack.begin()->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
collector_t::stack()
|
||||
{
|
||||
assert(m_tu_decorators_stack.size() >= 1);
|
||||
m_tu_decorators_stack.insert(m_tu_decorators_stack.begin(), std::vector<base_ptr>());
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
std::vector<base_ptr>
|
||||
collector_t::get_lazy_decorators() const
|
||||
{
|
||||
return *m_tu_decorators_stack.begin();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -68,10 +92,28 @@ collector::reset()
|
||||
// ************** decorator::base ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
collector&
|
||||
collector_t&
|
||||
base::operator*() const
|
||||
{
|
||||
return collector::instance() * *this;
|
||||
return collector_t::instance() * *this;
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** decorator::stack_decorator ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
collector_t&
|
||||
stack_decorator::operator*() const
|
||||
{
|
||||
collector_t& instance = collector_t::instance();
|
||||
instance.stack();
|
||||
return instance * *this;
|
||||
}
|
||||
|
||||
void
|
||||
stack_decorator::apply( test_unit& tu )
|
||||
{
|
||||
// does nothing by definition
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/detail/config.hpp>
|
||||
#include <boost/test/detail/workaround.hpp>
|
||||
#include <boost/test/detail/throw_exception.hpp>
|
||||
#include <boost/test/execution_monitor.hpp>
|
||||
#include <boost/test/debug.hpp>
|
||||
@@ -35,6 +34,7 @@
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#include <boost/exception/get_error_info.hpp> // for get_error_info
|
||||
#include <boost/exception/current_exception_cast.hpp> // for current_exception_cast
|
||||
#include <boost/exception/diagnostic_information.hpp>
|
||||
#endif
|
||||
|
||||
// STL
|
||||
@@ -47,28 +47,32 @@
|
||||
#include <cassert> // for assert
|
||||
#include <cstddef> // for NULL
|
||||
#include <cstdio> // for vsnprintf
|
||||
#include <stdio.h>
|
||||
#include <cstdarg> // for varargs
|
||||
#include <stdarg.h>
|
||||
#include <cmath> // for ceil
|
||||
|
||||
#include <iostream> // for varargs
|
||||
|
||||
#ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std { using ::strerror; using ::strlen; using ::strncat; }
|
||||
namespace std { using ::strerror; using ::strlen; using ::strncat; using ::ceil; }
|
||||
#endif
|
||||
|
||||
// to use vsnprintf
|
||||
#if defined(__SUNPRO_CC) || defined(__SunOS)
|
||||
# include <stdio.h>
|
||||
# include <stdarg.h>
|
||||
#if defined(__SUNPRO_CC) || defined(__SunOS) || defined(__QNXNTO__) || defined(__VXWORKS__)
|
||||
using std::va_list;
|
||||
#endif
|
||||
|
||||
// to use vsnprintf
|
||||
#if defined(__QNXNTO__)
|
||||
# include <stdio.h>
|
||||
using std::va_list;
|
||||
#if defined(__VXWORKS__)
|
||||
# define BOOST_TEST_LIMITED_SIGNAL_DETAILS
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_SEH_BASED_SIGNAL_HANDLING
|
||||
|
||||
# if !defined(_WIN32_WINNT) // WinXP
|
||||
# define _WIN32_WINNT 0x0501
|
||||
# endif
|
||||
|
||||
# include <windows.h>
|
||||
|
||||
# if defined(__MWERKS__) || (defined(_MSC_VER) && !defined(UNDER_CE))
|
||||
@@ -102,6 +106,10 @@ using std::va_list;
|
||||
# define BOOST_TEST_CRT_SET_HOOK(H) (void*)(H)
|
||||
# endif
|
||||
|
||||
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) /* WinXP */
|
||||
# define BOOST_TEST_WIN32_WAITABLE_TIMERS
|
||||
# endif
|
||||
|
||||
# if (!BOOST_WORKAROUND(_MSC_VER, >= 1400 ) && \
|
||||
!defined(BOOST_COMO)) || defined(UNDER_CE)
|
||||
|
||||
@@ -210,7 +218,8 @@ namespace detail {
|
||||
# define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) std::vsnprintf( (a1), (a2), (a3), (a4) )
|
||||
#elif BOOST_WORKAROUND(_MSC_VER, <= 1310) || \
|
||||
BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3000)) || \
|
||||
defined(UNDER_CE)
|
||||
defined(UNDER_CE) || \
|
||||
(defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
|
||||
# define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) _vsnprintf( (a1), (a2), (a3), (a4) )
|
||||
#else
|
||||
# define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) vsnprintf( (a1), (a2), (a3), (a4) )
|
||||
@@ -363,11 +372,17 @@ system_signal_exception::report() const
|
||||
return; // no error actually occur?
|
||||
|
||||
switch( m_sig_info->si_code ) {
|
||||
#ifdef __VXWORKS__
|
||||
// a bit of a hack to adapt code to small m_sig_info VxWorks uses
|
||||
#define si_addr si_value.sival_int
|
||||
#define si_band si_value.sival_int
|
||||
#else
|
||||
case SI_USER:
|
||||
report_error( execution_exception::system_error,
|
||||
"signal: generated by kill() (or family); uid=%d; pid=%d",
|
||||
(int)m_sig_info->si_uid, (int)m_sig_info->si_pid );
|
||||
break;
|
||||
#endif
|
||||
case SI_QUEUE:
|
||||
report_error( execution_exception::system_error,
|
||||
"signal: sent by sigqueue()" );
|
||||
@@ -686,7 +701,7 @@ signal_action::~signal_action()
|
||||
class signal_handler {
|
||||
public:
|
||||
// Constructor
|
||||
explicit signal_handler( bool catch_system_errors, bool detect_fpe, unsigned timeout, bool attach_dbg, char* alt_stack );
|
||||
explicit signal_handler( bool catch_system_errors, bool detect_fpe, unsigned timeout_microseconds, bool attach_dbg, char* alt_stack );
|
||||
|
||||
// Destructor
|
||||
~signal_handler();
|
||||
@@ -709,7 +724,7 @@ public:
|
||||
private:
|
||||
// Data members
|
||||
signal_handler* m_prev_handler;
|
||||
unsigned m_timeout;
|
||||
unsigned m_timeout_microseconds;
|
||||
|
||||
// Note: We intentionality do not catch SIGCHLD. Users have to deal with it themselves
|
||||
signal_action m_ILL_action;
|
||||
@@ -733,24 +748,24 @@ signal_handler* signal_handler::s_active_handler = signal_handler_ptr();
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
signal_handler::signal_handler( bool catch_system_errors, bool detect_fpe, unsigned timeout, bool attach_dbg, char* alt_stack )
|
||||
signal_handler::signal_handler( bool catch_system_errors, bool detect_fpe, unsigned timeout_microseconds, bool attach_dbg, char* alt_stack )
|
||||
: m_prev_handler( s_active_handler )
|
||||
, m_timeout( timeout )
|
||||
, m_ILL_action ( SIGILL , catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_FPE_action ( SIGFPE , detect_fpe , attach_dbg, alt_stack )
|
||||
, m_SEGV_action( SIGSEGV, catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_BUS_action ( SIGBUS , catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_timeout_microseconds( timeout_microseconds )
|
||||
, m_ILL_action ( SIGILL , catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_FPE_action ( SIGFPE , detect_fpe , attach_dbg, alt_stack )
|
||||
, m_SEGV_action( SIGSEGV, catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_BUS_action ( SIGBUS , catch_system_errors, attach_dbg, alt_stack )
|
||||
#ifdef BOOST_TEST_CATCH_SIGPOLL
|
||||
, m_POLL_action( SIGPOLL, catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_POLL_action( SIGPOLL, catch_system_errors, attach_dbg, alt_stack )
|
||||
#endif
|
||||
, m_ABRT_action( SIGABRT, catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_ALRM_action( SIGALRM, timeout > 0 , attach_dbg, alt_stack )
|
||||
, m_ABRT_action( SIGABRT, catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_ALRM_action( SIGALRM, timeout_microseconds > 0, attach_dbg, alt_stack )
|
||||
{
|
||||
s_active_handler = this;
|
||||
|
||||
if( m_timeout > 0 ) {
|
||||
if( m_timeout_microseconds > 0 ) {
|
||||
::alarm( 0 );
|
||||
::alarm( timeout );
|
||||
::alarm( static_cast<unsigned int>(std::ceil(timeout_microseconds / 1E6) )); // alarm has a precision to the seconds
|
||||
}
|
||||
|
||||
#ifdef BOOST_TEST_USE_ALT_STACK
|
||||
@@ -776,7 +791,7 @@ signal_handler::~signal_handler()
|
||||
{
|
||||
assert( s_active_handler == this );
|
||||
|
||||
if( m_timeout > 0 )
|
||||
if( m_timeout_microseconds > 0 )
|
||||
::alarm( 0 );
|
||||
|
||||
#ifdef BOOST_TEST_USE_ALT_STACK
|
||||
@@ -892,8 +907,10 @@ public:
|
||||
, m_se_id( 0 )
|
||||
, m_fault_address( 0 )
|
||||
, m_dir( false )
|
||||
, m_timeout( false )
|
||||
{}
|
||||
|
||||
void set_timed_out();
|
||||
void report() const;
|
||||
int operator()( unsigned id, _EXCEPTION_POINTERS* exps );
|
||||
|
||||
@@ -904,6 +921,7 @@ private:
|
||||
unsigned m_se_id;
|
||||
void* m_fault_address;
|
||||
bool m_dir;
|
||||
bool m_timeout;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -918,6 +936,14 @@ seh_catch_preventer( unsigned /* id */, _EXCEPTION_POINTERS* /* exps */ )
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
system_signal_exception::set_timed_out()
|
||||
{
|
||||
m_timeout = true;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
int
|
||||
system_signal_exception::operator()( unsigned id, _EXCEPTION_POINTERS* exps )
|
||||
{
|
||||
@@ -1069,7 +1095,12 @@ system_signal_exception::report() const
|
||||
break;
|
||||
|
||||
default:
|
||||
detail::report_error( execution_exception::system_error, "unrecognized exception. Id: 0x%08lx", m_se_id );
|
||||
if( m_timeout ) {
|
||||
detail::report_error(execution_exception::timeout_error, "timeout while executing function");
|
||||
}
|
||||
else {
|
||||
detail::report_error( execution_exception::system_error, "unrecognized exception. Id: 0x%08lx", m_se_id );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1128,6 +1159,31 @@ execution_monitor::catch_signals( boost::function<int ()> const& F )
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(BOOST_TEST_WIN32_WAITABLE_TIMERS)
|
||||
HANDLE htimer = INVALID_HANDLE_VALUE;
|
||||
BOOL bTimerSuccess = FALSE;
|
||||
|
||||
if( p_timeout ) {
|
||||
htimer = ::CreateWaitableTimer(
|
||||
NULL,
|
||||
TRUE,
|
||||
TEXT("Boost.Test timer"));
|
||||
|
||||
if( htimer != INVALID_HANDLE_VALUE ) {
|
||||
LARGE_INTEGER liDueTime;
|
||||
liDueTime.QuadPart = - static_cast<signed long int>(p_timeout) * 10; // resolution of 100 ns
|
||||
|
||||
bTimerSuccess = ::SetWaitableTimer(
|
||||
htimer,
|
||||
&liDueTime,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
FALSE); // Do not restore a suspended system
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
detail::system_signal_exception SSE( this );
|
||||
|
||||
int ret_val = 0;
|
||||
@@ -1141,8 +1197,26 @@ execution_monitor::catch_signals( boost::function<int ()> const& F )
|
||||
__except( SSE( GetExceptionCode(), GetExceptionInformation() ) ) {
|
||||
throw SSE;
|
||||
}
|
||||
|
||||
// we check for time outs: we do not have any signaling facility on Win32
|
||||
// however, we signal a timeout as a hard error as for the other operating systems
|
||||
// and throw the signal error handler
|
||||
if( bTimerSuccess && htimer != INVALID_HANDLE_VALUE) {
|
||||
if (::WaitForSingleObject(htimer, 0) == WAIT_OBJECT_0) {
|
||||
SSE.set_timed_out();
|
||||
throw SSE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
__finally {
|
||||
|
||||
#if defined(BOOST_TEST_WIN32_WAITABLE_TIMERS)
|
||||
if( htimer != INVALID_HANDLE_VALUE ) {
|
||||
::CloseHandle(htimer);
|
||||
}
|
||||
#endif
|
||||
|
||||
if( l_catch_system_errors ) {
|
||||
BOOST_TEST_CRT_SET_HOOK( old_crt_hook );
|
||||
|
||||
@@ -1198,7 +1272,7 @@ execution_monitor::execute( boost::function<int ()> const& F )
|
||||
|
||||
BOOST_TEST_I_TRY {
|
||||
detail::fpe_except_guard G( p_detect_fp_exceptions );
|
||||
unit_test::ut_detail::ignore_unused_variable_warning( G );
|
||||
boost::ignore_unused( G );
|
||||
|
||||
return catch_signals( F );
|
||||
}
|
||||
@@ -1217,6 +1291,16 @@ execution_monitor::execute( boost::function<int ()> const& F )
|
||||
{ detail::report_error( execution_exception::cpp_exception_error,
|
||||
"std::string: %s", ex.c_str() ); }
|
||||
|
||||
// boost::exception (before std::exception, with extended diagnostic)
|
||||
catch( boost::exception const& ex )
|
||||
{ detail::report_error( execution_exception::cpp_exception_error,
|
||||
&ex,
|
||||
#if defined(BOOST_NO_TYPEID) || defined(BOOST_NO_RTTI)
|
||||
"unknown boost::exception" ); }
|
||||
#else
|
||||
boost::diagnostic_information(ex).c_str() ); }
|
||||
#endif
|
||||
|
||||
// std:: exceptions
|
||||
#if defined(BOOST_NO_TYPEID) || defined(BOOST_NO_RTTI)
|
||||
#define CATCH_AND_REPORT_STD_EXCEPTION( ex_name ) \
|
||||
@@ -1235,15 +1319,8 @@ execution_monitor::execute( boost::function<int ()> const& F )
|
||||
#endif
|
||||
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::bad_alloc )
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::bad_cast )
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::bad_typeid )
|
||||
#else
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::bad_cast )
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::bad_typeid )
|
||||
#endif
|
||||
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::bad_exception )
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::domain_error )
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::invalid_argument )
|
||||
@@ -1257,15 +1334,6 @@ execution_monitor::execute( boost::function<int ()> const& F )
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::exception )
|
||||
#undef CATCH_AND_REPORT_STD_EXCEPTION
|
||||
|
||||
catch( boost::exception const& ex )
|
||||
{ detail::report_error( execution_exception::cpp_exception_error,
|
||||
&ex,
|
||||
#if defined(BOOST_NO_TYPEID) || defined(BOOST_NO_RTTI)
|
||||
"unknown boost::exception" ); }
|
||||
#else
|
||||
typeid(ex).name() ); }
|
||||
#endif
|
||||
|
||||
// system errors
|
||||
catch( system_error const& ex )
|
||||
{ detail::report_error( execution_exception::cpp_exception_error,
|
||||
@@ -1342,6 +1410,12 @@ execution_exception::location::location( char const* file_name, size_t line_num,
|
||||
, m_function( func )
|
||||
{}
|
||||
|
||||
execution_exception::location::location(const_string file_name, size_t line_num, char const* func )
|
||||
: m_file_name( file_name )
|
||||
, m_line_num( line_num )
|
||||
, m_function( func )
|
||||
{}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
|
||||
@@ -27,12 +27,14 @@
|
||||
#include <boost/test/results_collector.hpp>
|
||||
#include <boost/test/progress_monitor.hpp>
|
||||
#include <boost/test/results_reporter.hpp>
|
||||
#include <boost/test/test_framework_init_observer.hpp>
|
||||
|
||||
#include <boost/test/tree/observer.hpp>
|
||||
#include <boost/test/tree/test_unit.hpp>
|
||||
#include <boost/test/tree/visitor.hpp>
|
||||
#include <boost/test/tree/traverse.hpp>
|
||||
#include <boost/test/tree/test_case_counter.hpp>
|
||||
#include <boost/test/tree/global_fixture.hpp>
|
||||
|
||||
#if BOOST_TEST_SUPPORT_TOKEN_ITERATOR
|
||||
#include <boost/test/utils/iterator/token_iterator.hpp>
|
||||
@@ -46,7 +48,7 @@
|
||||
#include <boost/test/detail/throw_exception.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/test/utils/timer.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
// STL
|
||||
@@ -56,6 +58,10 @@
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <numeric>
|
||||
#include <cmath>
|
||||
#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
|
||||
#include <iterator>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std { using ::time; using ::srand; }
|
||||
@@ -68,6 +74,7 @@ namespace std { using ::time; using ::srand; }
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace framework {
|
||||
|
||||
namespace impl {
|
||||
|
||||
// ************************************************************************** //
|
||||
@@ -342,12 +349,10 @@ public:
|
||||
, m_dep_collector( dep_collector )
|
||||
{}
|
||||
|
||||
private:
|
||||
// test_tree_visitor interface
|
||||
virtual bool visit( test_unit const& tu )
|
||||
{
|
||||
const_cast<test_unit&>(tu).p_run_status.value = m_new_status == test_unit::RS_INVALID ? tu.p_default_status : m_new_status;
|
||||
|
||||
if( m_dep_collector ) {
|
||||
BOOST_TEST_FOREACH( test_unit_id, dep_id, tu.p_dependencies.get() ) {
|
||||
test_unit const& dep = framework::get( dep_id, TUT_ANY );
|
||||
@@ -364,6 +369,7 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// Data members
|
||||
test_unit::run_status m_new_status;
|
||||
test_unit_id_list* m_dep_collector;
|
||||
@@ -435,18 +441,59 @@ parse_filters( test_unit_id master_tu_id, test_unit_id_list& tu_to_enable, test_
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
|
||||
|
||||
// a poor man's implementation of random_shuffle
|
||||
template< class RandomIt, class RandomFunc >
|
||||
void random_shuffle( RandomIt first, RandomIt last, RandomFunc &r )
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomIt>::difference_type difference_type;
|
||||
difference_type n = last - first;
|
||||
for (difference_type i = n-1; i > 0; --i) {
|
||||
difference_type j = r(i+1);
|
||||
if (j != i) {
|
||||
using std::swap;
|
||||
swap(first[i], first[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// A simple handle for registering the global fixtures to the master test suite
|
||||
// without deleting an existing static object (the global fixture itself) when the program
|
||||
// terminates (shared_ptr).
|
||||
class global_fixture_handle : public test_unit_fixture {
|
||||
public:
|
||||
global_fixture_handle(test_unit_fixture* fixture) : m_global_fixture(fixture) {}
|
||||
~global_fixture_handle() {}
|
||||
|
||||
virtual void setup() {
|
||||
m_global_fixture->setup();
|
||||
}
|
||||
virtual void teardown() {
|
||||
m_global_fixture->teardown();
|
||||
}
|
||||
|
||||
private:
|
||||
test_unit_fixture* m_global_fixture;
|
||||
};
|
||||
|
||||
|
||||
} // namespace impl
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** framework::state ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
unsigned const TIMEOUT_EXCEEDED = static_cast<unsigned>( -1 );
|
||||
unsigned long int const TIMEOUT_EXCEEDED = static_cast<unsigned long int>( -1 );
|
||||
|
||||
class state {
|
||||
public:
|
||||
state()
|
||||
: m_curr_test_case( INV_TEST_UNIT_ID )
|
||||
: m_master_test_suite( 0 )
|
||||
, m_curr_test_unit( INV_TEST_UNIT_ID )
|
||||
, m_next_test_case_id( MIN_TEST_CASE_ID )
|
||||
, m_next_test_suite_id( MIN_TEST_SUITE_ID )
|
||||
, m_test_in_progress( false )
|
||||
@@ -565,13 +612,27 @@ public:
|
||||
|
||||
tu_to_enable.pop_back();
|
||||
|
||||
// 35. Ignore test units which already enabled
|
||||
// 35. Ignore test units which are already enabled
|
||||
if( tu.is_enabled() )
|
||||
continue;
|
||||
|
||||
// set new status and add all dependencies into tu_to_enable
|
||||
set_run_status enabler( test_unit::RS_ENABLED, &tu_to_enable );
|
||||
traverse_test_tree( tu.p_id, enabler, true );
|
||||
|
||||
// Add the dependencies of the parent suites, see trac #13149
|
||||
test_unit_id parent_id = tu.p_parent_id;
|
||||
while( parent_id != INV_TEST_UNIT_ID
|
||||
&& parent_id != master_tu_id )
|
||||
{
|
||||
// we do not use the traverse_test_tree as otherwise it would enable the sibblings and subtree
|
||||
// of the test case we want to enable (we need to enable the parent suites and their dependencies only)
|
||||
// the parent_id needs to be enabled in order to be properly parsed by finalize_run_status, the visit
|
||||
// does the job
|
||||
test_unit& tu_parent = framework::get( parent_id, TUT_ANY );
|
||||
enabler.visit( tu_parent );
|
||||
parent_id = tu_parent.p_parent_id;
|
||||
}
|
||||
}
|
||||
|
||||
// 40. Apply all disablers
|
||||
@@ -603,9 +664,9 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Executed the test tree with the root at specified test unit
|
||||
// Executes the test tree with the root at specified test unit
|
||||
execution_result execute_test_tree( test_unit_id tu_id,
|
||||
unsigned timeout = 0,
|
||||
unsigned long int timeout_microseconds = 0,
|
||||
random_generator_helper const * const p_random_generator = 0)
|
||||
{
|
||||
test_unit const& tu = framework::get( tu_id, TUT_ANY );
|
||||
@@ -617,15 +678,16 @@ public:
|
||||
|
||||
// 10. Check preconditions, including zero time left for execution and
|
||||
// successful execution of all dependencies
|
||||
if( timeout == TIMEOUT_EXCEEDED ) {
|
||||
if( timeout_microseconds == TIMEOUT_EXCEEDED ) {
|
||||
// notify all observers about skipped test unit
|
||||
BOOST_TEST_FOREACH( test_observer*, to, m_observers )
|
||||
to->test_unit_skipped( tu, "timeout for the test unit is exceeded" );
|
||||
|
||||
return unit_test_monitor_t::os_timeout;
|
||||
}
|
||||
else if( timeout == 0 || timeout > tu.p_timeout ) // deduce timeout for this test unit
|
||||
timeout = tu.p_timeout;
|
||||
else if( timeout_microseconds == 0 || (tu.p_timeout > 0 && timeout_microseconds > (tu.p_timeout * 1000000) ) ) // deduce timeout for this test unit
|
||||
timeout_microseconds = tu.p_timeout * 1000000;
|
||||
|
||||
|
||||
test_tools::assertion_result const precondition_res = tu.check_preconditions();
|
||||
if( !precondition_res ) {
|
||||
@@ -633,7 +695,10 @@ public:
|
||||
BOOST_TEST_FOREACH( test_observer*, to, m_observers )
|
||||
to->test_unit_skipped( tu, precondition_res.message() );
|
||||
|
||||
return unit_test_monitor_t::precondition_failure;
|
||||
// It is not an error to skip the test if any of the parent tests
|
||||
// have failed. This one should be reported as skipped as if it was
|
||||
// disabled
|
||||
return unit_test_monitor_t::test_ok;
|
||||
}
|
||||
|
||||
// 20. Notify all observers about the start of the test unit
|
||||
@@ -642,17 +707,27 @@ public:
|
||||
|
||||
// 30. Execute setup fixtures if any; any failure here leads to test unit abortion
|
||||
BOOST_TEST_FOREACH( test_unit_fixture_ptr, F, tu.p_fixtures.get() ) {
|
||||
ut_detail::test_unit_id_restore restore_current_test_unit(m_curr_test_unit, tu.p_id);
|
||||
result = unit_test_monitor.execute_and_translate( boost::bind( &test_unit_fixture::setup, F ) );
|
||||
if( result != unit_test_monitor_t::test_ok )
|
||||
break;
|
||||
test_results const& test_rslt = unit_test::results_collector.results( m_curr_test_unit );
|
||||
if( test_rslt.aborted() ) {
|
||||
result = unit_test_monitor_t::test_setup_failure;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This is the time we are going to spend executing the test unit
|
||||
unsigned long elapsed = 0;
|
||||
// This is the time we are going to spend executing the test unit (in microseconds
|
||||
// as expected by test_observer::test_unit_finish)
|
||||
unsigned long elapsed_microseconds = 0;
|
||||
|
||||
if( result == unit_test_monitor_t::test_ok ) {
|
||||
// 40. We are going to time the execution
|
||||
boost::timer tu_timer;
|
||||
boost::unit_test::timer::timer tu_timer;
|
||||
|
||||
// we pass the random generator
|
||||
const random_generator_helper& rand_gen = p_random_generator ? *p_random_generator : random_generator_helper();
|
||||
|
||||
if( tu.p_type == TUT_SUITE ) {
|
||||
test_suite const& ts = static_cast<test_suite const&>( tu );
|
||||
@@ -661,16 +736,33 @@ public:
|
||||
typedef std::pair<counter_t,test_unit_id> value_type;
|
||||
|
||||
BOOST_TEST_FOREACH( value_type, chld, ts.m_ranked_children ) {
|
||||
unsigned chld_timeout = child_timeout( timeout, tu_timer.elapsed() );
|
||||
// tu_timer.elapsed() returns nanosec, timeout and child_timeout in microsec
|
||||
unsigned long int chld_timeout = child_timeout(
|
||||
timeout_microseconds,
|
||||
static_cast<unsigned long int>( microsecond_wall_time(tu_timer.elapsed()) ));
|
||||
|
||||
result = (std::min)( result, execute_test_tree( chld.second, chld_timeout ) );
|
||||
result = (std::min)( result, execute_test_tree( chld.second, chld_timeout, &rand_gen ) );
|
||||
|
||||
if( unit_test_monitor.is_critical_error( result ) )
|
||||
break;
|
||||
|
||||
// we check for the time elapsed. If this is too high, we fail the current suite and return from here
|
||||
elapsed_microseconds = static_cast<unsigned long int>( microsecond_wall_time(tu_timer.elapsed()) );
|
||||
|
||||
if( (timeout_microseconds > 0) && (elapsed_microseconds > timeout_microseconds) && (timeout_microseconds != TIMEOUT_EXCEEDED ) ) {
|
||||
BOOST_TEST_FOREACH( test_observer*, to, m_observers ) {
|
||||
to->test_unit_timed_out(tu);
|
||||
}
|
||||
result = (std::min)( result, unit_test_monitor_t::os_timeout );
|
||||
timeout_microseconds = TIMEOUT_EXCEEDED;
|
||||
//break;
|
||||
// we continue to explore the children, such that we can at least update their
|
||||
// status to skipped
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Go through ranges of chldren with the same dependency rank and shuffle them
|
||||
// Go through ranges of children with the same dependency rank and shuffle them
|
||||
// independently. Execute each subtree in this order
|
||||
test_unit_id_list children_with_the_same_rank;
|
||||
|
||||
@@ -686,22 +778,37 @@ public:
|
||||
it++;
|
||||
}
|
||||
|
||||
const random_generator_helper& rand_gen = p_random_generator ? *p_random_generator : random_generator_helper();
|
||||
|
||||
#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
|
||||
impl::random_shuffle( children_with_the_same_rank.begin(), children_with_the_same_rank.end(), rand_gen );
|
||||
#else
|
||||
std::random_shuffle( children_with_the_same_rank.begin(), children_with_the_same_rank.end(), rand_gen );
|
||||
#endif
|
||||
|
||||
BOOST_TEST_FOREACH( test_unit_id, chld, children_with_the_same_rank ) {
|
||||
unsigned chld_timeout = child_timeout( timeout, tu_timer.elapsed() );
|
||||
unsigned long int chld_timeout = child_timeout(
|
||||
timeout_microseconds,
|
||||
static_cast<unsigned long int>(microsecond_wall_time(tu_timer.elapsed())) );
|
||||
|
||||
result = (std::min)( result, execute_test_tree( chld, chld_timeout, &rand_gen ) );
|
||||
|
||||
if( unit_test_monitor.is_critical_error( result ) )
|
||||
break;
|
||||
|
||||
// we check for the time elapsed. If this is too high, we fail the current suite and return from here
|
||||
elapsed_microseconds = static_cast<unsigned long int>( microsecond_wall_time(tu_timer.elapsed()) );
|
||||
if( (timeout_microseconds > 0) && (elapsed_microseconds > timeout_microseconds) && (timeout_microseconds != TIMEOUT_EXCEEDED ) ) {
|
||||
BOOST_TEST_FOREACH( test_observer*, to, m_observers ) {
|
||||
to->test_unit_timed_out(tu);
|
||||
}
|
||||
result = (std::min)( result, unit_test_monitor_t::os_timeout );
|
||||
timeout_microseconds = TIMEOUT_EXCEEDED;
|
||||
//break;
|
||||
// we continue to explore the children, such that we can at least update their
|
||||
// status to skipped
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elapsed = static_cast<unsigned long>( tu_timer.elapsed() * 1e6 );
|
||||
}
|
||||
else { // TUT_CASE
|
||||
test_case const& tc = static_cast<test_case const&>( tu );
|
||||
@@ -710,18 +817,16 @@ public:
|
||||
m_context_idx = 0;
|
||||
|
||||
// setup current test case
|
||||
test_unit_id bkup = m_curr_test_case;
|
||||
m_curr_test_case = tc.p_id;
|
||||
ut_detail::test_unit_id_restore restore_current_test_unit(m_curr_test_unit, tc.p_id);
|
||||
|
||||
// execute the test case body
|
||||
result = unit_test_monitor.execute_and_translate( tc.p_test_func, timeout );
|
||||
elapsed = static_cast<unsigned long>( tu_timer.elapsed() * 1e6 );
|
||||
// execute the test case body, transforms the time out to seconds
|
||||
result = unit_test_monitor.execute_and_translate( tc.p_test_func, timeout_microseconds );
|
||||
elapsed_microseconds = static_cast<unsigned long int>( microsecond_wall_time(tu_timer.elapsed()) );
|
||||
|
||||
// cleanup leftover context
|
||||
m_context.clear();
|
||||
|
||||
// restore state and abort if necessary
|
||||
m_curr_test_case = bkup;
|
||||
// restore state (scope exit) and abort if necessary
|
||||
}
|
||||
}
|
||||
|
||||
@@ -729,6 +834,7 @@ public:
|
||||
if( !unit_test_monitor.is_critical_error( result ) ) {
|
||||
// execute teardown fixtures if any in reverse order
|
||||
BOOST_TEST_REVERSE_FOREACH( test_unit_fixture_ptr, F, tu.p_fixtures.get() ) {
|
||||
ut_detail::test_unit_id_restore restore_current_test_unit(m_curr_test_unit, tu.p_id);
|
||||
result = (std::min)( result, unit_test_monitor.execute_and_translate( boost::bind( &test_unit_fixture::teardown, F ), 0 ) );
|
||||
|
||||
if( unit_test_monitor.is_critical_error( result ) )
|
||||
@@ -744,21 +850,21 @@ public:
|
||||
|
||||
// notify all observers about completion
|
||||
BOOST_TEST_REVERSE_FOREACH( test_observer*, to, m_observers )
|
||||
to->test_unit_finish( tu, elapsed );
|
||||
to->test_unit_finish( tu, elapsed_microseconds );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
unsigned child_timeout( unsigned tu_timeout, double elapsed )
|
||||
unsigned long int child_timeout( unsigned long tu_timeout_microseconds, unsigned long elpsed_microsec )
|
||||
{
|
||||
if( tu_timeout == 0U )
|
||||
return 0U;
|
||||
if( tu_timeout_microseconds == 0UL || tu_timeout_microseconds == TIMEOUT_EXCEEDED)
|
||||
return tu_timeout_microseconds;
|
||||
|
||||
unsigned elpsed_sec = static_cast<unsigned>(elapsed); // rounding to number of whole seconds
|
||||
|
||||
return tu_timeout > elpsed_sec ? tu_timeout - elpsed_sec : TIMEOUT_EXCEEDED;
|
||||
return tu_timeout_microseconds > elpsed_microsec ?
|
||||
tu_timeout_microseconds - elpsed_microsec
|
||||
: TIMEOUT_EXCEEDED;
|
||||
}
|
||||
|
||||
struct priority_order {
|
||||
@@ -787,7 +893,7 @@ public:
|
||||
master_test_suite_t* m_master_test_suite;
|
||||
std::vector<test_suite*> m_auto_test_suites;
|
||||
|
||||
test_unit_id m_curr_test_case;
|
||||
test_unit_id m_curr_test_unit;
|
||||
test_unit_store m_test_units;
|
||||
|
||||
test_unit_id m_next_test_case_id;
|
||||
@@ -799,6 +905,8 @@ public:
|
||||
context_data m_context;
|
||||
int m_context_idx;
|
||||
|
||||
std::set<global_fixture*> m_global_fixtures;
|
||||
|
||||
boost::execution_monitor m_aux_em;
|
||||
|
||||
std::map<output_format, runtime_config::stream_holder> m_log_sinks;
|
||||
@@ -838,6 +946,30 @@ struct sum_to_first_only {
|
||||
bool is_first;
|
||||
};
|
||||
|
||||
void
|
||||
shutdown_loggers_and_reports()
|
||||
{
|
||||
s_frk_state().m_log_sinks.clear();
|
||||
s_frk_state().m_report_sink.setup( "stderr" );
|
||||
}
|
||||
|
||||
void
|
||||
unregister_global_fixture_and_configuration()
|
||||
{
|
||||
// we make a copy as the set will change in the iteration
|
||||
std::set<global_fixture*> gfixture_copy(s_frk_state().m_global_fixtures);
|
||||
BOOST_TEST_FOREACH( global_fixture*, tuf, gfixture_copy ) {
|
||||
tuf->unregister_from_framework();
|
||||
}
|
||||
s_frk_state().m_global_fixtures.clear();
|
||||
|
||||
state::observer_store gobserver_copy(s_frk_state().m_observers);
|
||||
BOOST_TEST_FOREACH( test_observer*, to, gobserver_copy ) {
|
||||
framework::deregister_observer( *to );
|
||||
}
|
||||
s_frk_state().m_observers.clear();
|
||||
}
|
||||
|
||||
void
|
||||
setup_loggers()
|
||||
{
|
||||
@@ -857,8 +989,15 @@ setup_loggers()
|
||||
unit_test_log.set_format( format );
|
||||
|
||||
runtime_config::stream_holder& stream_logger = s_frk_state().m_log_sinks[format];
|
||||
if( runtime_config::has( runtime_config::btrt_log_sink ) )
|
||||
stream_logger.setup( runtime_config::get<std::string>( runtime_config::btrt_log_sink ) );
|
||||
if( runtime_config::has( runtime_config::btrt_log_sink ) ) {
|
||||
// we remove all streams in this case, so we do not specify the format
|
||||
boost::function< void () > log_cleaner = boost::bind( &unit_test_log_t::set_stream,
|
||||
&unit_test_log,
|
||||
boost::ref(std::cout)
|
||||
);
|
||||
stream_logger.setup( runtime_config::get<std::string>( runtime_config::btrt_log_sink ),
|
||||
log_cleaner );
|
||||
}
|
||||
unit_test_log.set_stream( stream_logger.ref() );
|
||||
}
|
||||
else
|
||||
@@ -970,7 +1109,6 @@ setup_loggers()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_TEST_I_ASSRT( formatter_log_level != invalid_log_level,
|
||||
boost::runtime::access_to_missing_argument()
|
||||
<< "Unable to determine the log level from '"
|
||||
@@ -985,12 +1123,18 @@ setup_loggers()
|
||||
unit_test_log.set_threshold_level( format, formatter_log_level );
|
||||
|
||||
runtime_config::stream_holder& stream_logger = s_frk_state().m_log_sinks[format];
|
||||
boost::function< void () > log_cleaner = boost::bind( &unit_test_log_t::set_stream,
|
||||
&unit_test_log,
|
||||
format,
|
||||
boost::ref(std::cout) );
|
||||
if( ++current_format_specs != utils::string_token_iterator() &&
|
||||
current_format_specs->size() ) {
|
||||
stream_logger.setup( *current_format_specs );
|
||||
stream_logger.setup( *current_format_specs,
|
||||
log_cleaner );
|
||||
}
|
||||
else {
|
||||
stream_logger.setup( formatter->get_default_stream_description() );
|
||||
stream_logger.setup( formatter->get_default_stream_description(),
|
||||
log_cleaner );
|
||||
}
|
||||
unit_test_log.set_stream( format, stream_logger.ref() );
|
||||
}
|
||||
@@ -1036,13 +1180,20 @@ init( init_unit_test_func init_func, int argc, char* argv[] )
|
||||
results_reporter::set_level( runtime_config::get<report_level>( runtime_config::btrt_report_level ) );
|
||||
results_reporter::set_format( runtime_config::get<output_format>( runtime_config::btrt_report_format ) );
|
||||
|
||||
if( runtime_config::has( runtime_config::btrt_report_sink ) )
|
||||
s_frk_state().m_report_sink.setup( runtime_config::get<std::string>( runtime_config::btrt_report_sink ) );
|
||||
if( runtime_config::has( runtime_config::btrt_report_sink ) ) {
|
||||
boost::function< void () > report_cleaner = boost::bind( &results_reporter::set_stream,
|
||||
boost::ref(std::cerr)
|
||||
);
|
||||
s_frk_state().m_report_sink.setup( runtime_config::get<std::string>( runtime_config::btrt_report_sink ),
|
||||
report_cleaner );
|
||||
}
|
||||
|
||||
results_reporter::set_stream( s_frk_state().m_report_sink.ref() );
|
||||
|
||||
// 40. Register default test observers
|
||||
register_observer( results_collector );
|
||||
register_observer( unit_test_log );
|
||||
register_observer( framework_init_observer );
|
||||
|
||||
if( runtime_config::get<bool>( runtime_config::btrt_show_progress ) ) {
|
||||
progress_monitor.set_stream( std::cout ); // defaults to stdout
|
||||
@@ -1078,9 +1229,18 @@ finalize_setup_phase( test_unit_id master_tu_id )
|
||||
master_tu_id = master_test_suite().p_id;
|
||||
|
||||
// 10. Apply all decorators to the auto test units
|
||||
// 10. checks for consistency (duplicate names, etc)
|
||||
class apply_decorators : public test_tree_visitor {
|
||||
private:
|
||||
// test_tree_visitor interface
|
||||
|
||||
virtual bool test_suite_start( test_suite const& ts)
|
||||
{
|
||||
const_cast<test_suite&>(ts).generate();
|
||||
const_cast<test_suite&>(ts).check_for_duplicate_test_cases();
|
||||
return test_tree_visitor::test_suite_start(ts);
|
||||
}
|
||||
|
||||
virtual bool visit( test_unit const& tu )
|
||||
{
|
||||
BOOST_TEST_FOREACH( decorator::base_ptr, d, tu.p_decorators.get() )
|
||||
@@ -1116,6 +1276,13 @@ test_in_progress()
|
||||
void
|
||||
shutdown()
|
||||
{
|
||||
// shuts down the loggers singleton to avoid any further reference to the
|
||||
// framework during the destruction of those
|
||||
impl::shutdown_loggers_and_reports();
|
||||
|
||||
// unregisters any global fixture and configuration object
|
||||
impl::unregister_global_fixture_and_configuration();
|
||||
|
||||
// eliminating some fake memory leak reports. See for more details:
|
||||
// http://connect.microsoft.com/VisualStudio/feedback/details/106937/memory-leaks-reported-by-debug-crt-inside-typeinfo-name
|
||||
|
||||
@@ -1235,6 +1402,30 @@ deregister_observer( test_observer& to )
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** register_global_fixture ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
void
|
||||
register_global_fixture( global_fixture& tuf )
|
||||
{
|
||||
impl::s_frk_state().m_global_fixtures.insert( &tuf );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** deregister_global_fixture ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
void
|
||||
deregister_global_fixture( global_fixture &tuf )
|
||||
{
|
||||
impl::s_frk_state().m_global_fixtures.erase( &tuf );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** add_context ************** //
|
||||
// ************************************************************************** //
|
||||
@@ -1363,7 +1554,14 @@ current_auto_test_suite( test_suite* ts, bool push_or_pop )
|
||||
test_case const&
|
||||
current_test_case()
|
||||
{
|
||||
return get<test_case>( impl::s_frk_state().m_curr_test_case );
|
||||
return get<test_case>( impl::s_frk_state().m_curr_test_unit );
|
||||
}
|
||||
|
||||
|
||||
test_unit const&
|
||||
current_test_unit()
|
||||
{
|
||||
return *impl::s_frk_state().m_test_units[impl::s_frk_state().m_curr_test_unit];
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -1371,7 +1569,7 @@ current_test_case()
|
||||
test_unit_id
|
||||
current_test_case_id()
|
||||
{
|
||||
return impl::s_frk_state().m_curr_test_case;
|
||||
return impl::s_frk_state().m_curr_test_unit;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -1396,6 +1594,17 @@ get( test_unit_id id, test_unit_type t )
|
||||
// ************** framework::run ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template <class Cont>
|
||||
struct swap_on_delete {
|
||||
swap_on_delete(Cont& c1, Cont& c2) : m_c1(c1), m_c2(c2){}
|
||||
~swap_on_delete() {
|
||||
m_c1.swap(m_c2);
|
||||
}
|
||||
|
||||
Cont& m_c1;
|
||||
Cont& m_c2;
|
||||
};
|
||||
|
||||
void
|
||||
run( test_unit_id id, bool continue_test )
|
||||
{
|
||||
@@ -1414,39 +1623,93 @@ run( test_unit_id id, bool continue_test )
|
||||
|
||||
bool was_in_progress = framework::test_in_progress();
|
||||
bool call_start_finish = !continue_test || !was_in_progress;
|
||||
|
||||
impl::s_frk_state().m_test_in_progress = true;
|
||||
bool init_ok = true;
|
||||
const_string setup_error;
|
||||
|
||||
if( call_start_finish ) {
|
||||
// indicates the framework that no test is in progress now if observers need to be notified
|
||||
impl::s_frk_state().m_test_in_progress = false;
|
||||
// unit_test::framework_init_observer will get cleared first
|
||||
BOOST_TEST_FOREACH( test_observer*, to, impl::s_frk_state().m_observers ) {
|
||||
BOOST_TEST_I_TRY {
|
||||
impl::s_frk_state().m_aux_em.vexecute( boost::bind( &test_observer::test_start, to, tcc.p_count ) );
|
||||
ut_detail::test_unit_id_restore restore_current_test_unit(impl::s_frk_state().m_curr_test_unit, id);
|
||||
unit_test_monitor_t::error_level result = unit_test_monitor.execute_and_translate( boost::bind( &test_observer::test_start, to, tcc.p_count ) );
|
||||
if( init_ok ) {
|
||||
if( result != unit_test_monitor_t::test_ok ) {
|
||||
init_ok = false;
|
||||
}
|
||||
else {
|
||||
if( unit_test::framework_init_observer.has_failed() ) {
|
||||
init_ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_TEST_I_CATCH( execution_exception, ex ) {
|
||||
BOOST_TEST_SETUP_ASSERT( false, ex.what() );
|
||||
if( init_ok ) {
|
||||
// log only the first error
|
||||
init_ok = false;
|
||||
setup_error = ex.what();
|
||||
}
|
||||
// break; // we should continue otherwise loggers may have improper structure (XML start missing for instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned seed = runtime_config::get<unsigned>( runtime_config::btrt_random_seed );
|
||||
switch( seed ) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
seed = static_cast<unsigned>( std::rand() ^ std::time( 0 ) ); // better init using std::rand() ^ ...
|
||||
default:
|
||||
BOOST_TEST_FRAMEWORK_MESSAGE( "Test cases order is shuffled using seed: " << seed );
|
||||
std::srand( seed );
|
||||
if( init_ok ) {
|
||||
|
||||
// attaching the global fixtures to the main entry point
|
||||
test_unit& entry_test_unit = framework::get( id, TUT_ANY );
|
||||
std::vector<test_unit_fixture_ptr> v_saved_fixture(entry_test_unit.p_fixtures.value.begin(),
|
||||
entry_test_unit.p_fixtures.value.end());
|
||||
|
||||
BOOST_TEST_FOREACH( test_unit_fixture*, tuf, impl::s_frk_state().m_global_fixtures ) {
|
||||
entry_test_unit.p_fixtures.value.insert( entry_test_unit.p_fixtures.value.begin(),
|
||||
test_unit_fixture_ptr(new impl::global_fixture_handle(tuf)) );
|
||||
}
|
||||
|
||||
swap_on_delete< std::vector<test_unit_fixture_ptr> > raii_fixture(v_saved_fixture, entry_test_unit.p_fixtures.value);
|
||||
|
||||
// now work in progress
|
||||
impl::s_frk_state().m_test_in_progress = true;
|
||||
unsigned seed = runtime_config::get<unsigned>( runtime_config::btrt_random_seed );
|
||||
switch( seed ) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
seed = static_cast<unsigned>( std::rand() ^ std::time( 0 ) ); // better init using std::rand() ^ ...
|
||||
BOOST_FALLTHROUGH;
|
||||
default:
|
||||
BOOST_TEST_FRAMEWORK_MESSAGE( "Test cases order is shuffled using seed: " << seed );
|
||||
std::srand( seed );
|
||||
}
|
||||
|
||||
// executing the test tree
|
||||
impl::s_frk_state().execute_test_tree( id );
|
||||
|
||||
// removing previously added global fixtures: dtor raii_fixture
|
||||
}
|
||||
|
||||
impl::s_frk_state().execute_test_tree( id );
|
||||
impl::s_frk_state().m_test_in_progress = false;
|
||||
|
||||
results_reporter::make_report( INV_REPORT_LEVEL, id );
|
||||
|
||||
unit_test::framework_init_observer.clear();
|
||||
if( call_start_finish ) {
|
||||
BOOST_TEST_REVERSE_FOREACH( test_observer*, to, impl::s_frk_state().m_observers )
|
||||
// indicates the framework that no test is in progress anymore if observers need to be notified
|
||||
// and this is a teardown, so assertions should not raise any exception otherwise an exception
|
||||
// might be raised in a dtor of a global fixture
|
||||
impl::s_frk_state().m_test_in_progress = false;
|
||||
BOOST_TEST_REVERSE_FOREACH( test_observer*, to, impl::s_frk_state().m_observers ) {
|
||||
ut_detail::test_unit_id_restore restore_current_test_unit(impl::s_frk_state().m_curr_test_unit, id);
|
||||
to->test_finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl::s_frk_state().m_test_in_progress = was_in_progress;
|
||||
|
||||
// propagates the init/teardown error if any
|
||||
BOOST_TEST_SETUP_ASSERT( init_ok && !unit_test::framework_init_observer.has_failed(), setup_error );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -1496,6 +1759,18 @@ test_unit_aborted( test_unit const& tu )
|
||||
to->test_unit_aborted( tu );
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** test_aborted ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
void
|
||||
test_aborted( )
|
||||
{
|
||||
BOOST_TEST_FOREACH( test_observer*, to, impl::s_frk_state().m_observers )
|
||||
to->test_aborted( );
|
||||
}
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace framework
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
// Boost
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
// STL
|
||||
#include <iostream>
|
||||
@@ -69,6 +70,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 +93,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 +103,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 +123,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 +180,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 +209,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 +226,50 @@ 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 ) {
|
||||
if(tr->p_timed_out)
|
||||
name += "-timed-execution";
|
||||
else
|
||||
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 +278,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 +286,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 +312,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 << "'";
|
||||
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(tc->p_file_name) << std::endl
|
||||
<< "- line: " << tc->p_line_num << std::endl
|
||||
;
|
||||
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 = static_cast<int>(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 +415,58 @@ 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;
|
||||
// unique test suite, without s, nesting not supported in CI
|
||||
if( m_ts.p_id == ts.p_id ) {
|
||||
m_stream << "<testsuite";
|
||||
|
||||
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;
|
||||
// think about: maybe we should add the number of fixtures of a test_suite as
|
||||
// independant tests (field p_fixtures).
|
||||
// same goes for the timed-execution: we can think of that as a separate test-unit
|
||||
// in the suite.
|
||||
// see https://llg.cubic.org/docs/junit/ and
|
||||
// http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java?view=markup
|
||||
m_stream
|
||||
// << "disabled=\"" << tr.p_test_cases_skipped << "\" "
|
||||
<< " tests" << utils::attr_value()
|
||||
<< tr.p_test_cases_passed
|
||||
+ tr.p_test_cases_failed
|
||||
// + tr.p_test_cases_aborted // aborted is also failed, we avoid counting it twice
|
||||
<< " 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
|
||||
+ tr.p_test_suites_timed_out
|
||||
+ tr.p_test_cases_timed_out
|
||||
- tr.p_test_cases_aborted // failed is not aborted in the Junit sense
|
||||
<< " 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;
|
||||
|
||||
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(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;
|
||||
}
|
||||
}
|
||||
|
||||
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 +474,13 @@ public:
|
||||
|
||||
virtual void test_suite_finish( test_suite const& ts )
|
||||
{
|
||||
if( m_ts.p_id != ts.p_id )
|
||||
if( m_ts.p_id == ts.p_id ) {
|
||||
write_testcase_system_out(runner_log, 0, false);
|
||||
write_testcase_system_err(runner_log, 0, 0);
|
||||
|
||||
m_stream << "</testsuite>";
|
||||
return;
|
||||
|
||||
write_testcase_system_out(runner_log, 0, false, 0);
|
||||
write_testcase_system_err(runner_log, 0, 0);
|
||||
|
||||
m_stream << "</testsuite>";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -439,15 +524,15 @@ 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*/, bool log_build_info )
|
||||
{
|
||||
m_display_build_info = true;
|
||||
m_display_build_info = log_build_info;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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
|
||||
@@ -457,17 +542,20 @@ 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
|
||||
boost::ignore_unused( tu );
|
||||
assert( tu.p_id == list_path_to_root.back() );
|
||||
list_path_to_root.pop_back();
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
boost::ignore_unused( tu );
|
||||
assert( tu.p_id == list_path_to_root.back() );
|
||||
//list_path_to_root.pop_back();
|
||||
}
|
||||
@@ -475,7 +563,26 @@ 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_timed_out( std::ostream& /*os*/, test_unit const& tu)
|
||||
{
|
||||
if(tu.p_type == TUT_SUITE)
|
||||
{
|
||||
// if we reach this call, it means that the test has already started and
|
||||
// test_unit_start has already been called on the tu.
|
||||
junit_impl::junit_log_helper& last_entry = get_current_log_entry();
|
||||
junit_impl::junit_log_helper::assertion_entry entry;
|
||||
entry.logentry_message = "test-suite time out";
|
||||
entry.logentry_type = "execution timeout";
|
||||
entry.log_entry = junit_impl::junit_log_helper::assertion_entry::log_entry_error;
|
||||
entry.output = "the current suite exceeded the allocated execution time";
|
||||
last_entry.assertion_entries.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
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 +594,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 +662,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 +672,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;
|
||||
@@ -578,7 +685,7 @@ junit_log_formatter::log_entry_start( std::ostream& ostr, log_entry_data const&
|
||||
last_entry.skipping = true;
|
||||
break;
|
||||
}
|
||||
// no break on purpose
|
||||
BOOST_FALLTHROUGH;
|
||||
}
|
||||
case unit_test_log_formatter::BOOST_UTL_ET_MESSAGE:
|
||||
{
|
||||
@@ -586,7 +693,7 @@ junit_log_formatter::log_entry_start( std::ostream& ostr, log_entry_data const&
|
||||
last_entry.skipping = true;
|
||||
break;
|
||||
}
|
||||
// no break on purpose
|
||||
BOOST_FALLTHROUGH;
|
||||
}
|
||||
case unit_test_log_formatter::BOOST_UTL_ET_WARNING:
|
||||
{
|
||||
@@ -638,7 +745,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 +769,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 +792,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 +815,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 +827,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)
|
||||
|
||||
@@ -108,6 +108,8 @@ plain_report_formatter::test_unit_report_start( test_unit const& tu, std::ostrea
|
||||
descr = "has passed";
|
||||
else if( tr.p_skipped )
|
||||
descr = "was skipped";
|
||||
else if( tr.p_timed_out )
|
||||
descr = "has timed out";
|
||||
else if( tr.p_aborted )
|
||||
descr = "was aborted";
|
||||
else
|
||||
@@ -122,8 +124,9 @@ plain_report_formatter::test_unit_report_start( test_unit const& tu, std::ostrea
|
||||
return;
|
||||
}
|
||||
|
||||
// aborted test case within failed ones, timed-out TC exclusive with failed/aborted
|
||||
counter_t total_assertions = tr.p_assertions_passed + tr.p_assertions_failed;
|
||||
counter_t total_tc = tr.p_test_cases_passed + tr.p_test_cases_warned + tr.p_test_cases_failed + tr.p_test_cases_skipped;
|
||||
counter_t total_tc = tr.p_test_cases_passed + tr.p_test_cases_warned + tr.p_test_cases_failed + tr.p_test_cases_skipped + tr.p_test_cases_timed_out;
|
||||
|
||||
if( total_assertions > 0 || total_tc > 0 || tr.p_warnings_failed > 0)
|
||||
ostr << " with:";
|
||||
@@ -134,6 +137,8 @@ plain_report_formatter::test_unit_report_start( test_unit const& tu, std::ostrea
|
||||
print_stat_value( ostr, tr.p_test_cases_passed , m_indent, total_tc , "test case", "passed" );
|
||||
print_stat_value( ostr, tr.p_test_cases_warned , m_indent, total_tc , "test case", "passed with warnings" );
|
||||
print_stat_value( ostr, tr.p_test_cases_failed , m_indent, total_tc , "test case", "failed" );
|
||||
print_stat_value( ostr, tr.p_test_cases_timed_out, m_indent, total_tc , "test case", "timed-out" );
|
||||
print_stat_value( ostr, tr.p_test_suites_timed_out, m_indent, tr.p_test_suites, "test suite", "timed-out" );
|
||||
print_stat_value( ostr, tr.p_test_cases_skipped, m_indent, total_tc , "test case", "skipped" );
|
||||
print_stat_value( ostr, tr.p_test_cases_aborted, m_indent, total_tc , "test case", "aborted" );
|
||||
print_stat_value( ostr, tr.p_assertions_passed , m_indent, total_assertions, "assertion", "passed" );
|
||||
@@ -174,6 +179,12 @@ plain_report_formatter::do_confirmation_report( test_unit const& tu, std::ostrea
|
||||
return;
|
||||
}
|
||||
|
||||
if( tr.p_timed_out ) {
|
||||
ostr << "*** The test " << tu.p_type_name << ' ' << quote() << tu.full_name() << " has timed out"
|
||||
<< "; see standard output for details\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if( tr.p_aborted ) {
|
||||
ostr << "*** The test " << tu.p_type_name << ' ' << quote() << tu.full_name() << " was aborted"
|
||||
<< "; see standard output for details\n";
|
||||
|
||||
@@ -52,7 +52,7 @@ struct progress_display {
|
||||
<< "\n|----|----|----|----|----|----|----|----|----|----|"
|
||||
<< std::endl;
|
||||
|
||||
if( !m_expected_count )
|
||||
if( !m_expected_count )
|
||||
m_expected_count = 1; // prevent divide by zero
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ struct progress_display {
|
||||
|
||||
// use of floating point ensures that both large and small counts
|
||||
// work correctly. static_cast<>() is also used several places
|
||||
// to suppress spurious compiler warnings.
|
||||
// to suppress spurious compiler warnings.
|
||||
unsigned int tics_needed = static_cast<unsigned int>(
|
||||
(static_cast<double>(m_count)/m_expected_count)*50.0 );
|
||||
|
||||
@@ -121,6 +121,10 @@ progress_monitor_impl& s_pm_impl() { static progress_monitor_impl the_inst; retu
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL(progress_monitor_t)
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
progress_monitor_t::test_start( counter_t test_cases_amount )
|
||||
{
|
||||
|
||||
@@ -5,11 +5,9 @@
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
// File : $RCSfile$
|
||||
//
|
||||
// Version : $Revision$
|
||||
//
|
||||
// Description : implements Unit Test results collecting facility.
|
||||
/// @file
|
||||
/// Test results collecting facility.
|
||||
///
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
|
||||
@@ -19,6 +17,7 @@
|
||||
#include <boost/test/unit_test_log.hpp>
|
||||
#include <boost/test/results_collector.hpp>
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <boost/test/execution_monitor.hpp>
|
||||
|
||||
#include <boost/test/tree/test_unit.hpp>
|
||||
#include <boost/test/tree/visitor.hpp>
|
||||
@@ -52,11 +51,31 @@ test_results::test_results()
|
||||
bool
|
||||
test_results::passed() const
|
||||
{
|
||||
// if it is skipped, it is not passed. However, if any children is not failed/aborted
|
||||
// then their skipped status is not taken into account.
|
||||
return !p_skipped &&
|
||||
p_test_cases_failed == 0 &&
|
||||
p_assertions_failed <= p_expected_failures &&
|
||||
p_test_cases_skipped == 0 &&
|
||||
!p_aborted;
|
||||
// p_test_cases_skipped == 0 &&
|
||||
!p_timed_out &&
|
||||
p_test_cases_timed_out == 0 &&
|
||||
!aborted();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
bool
|
||||
test_results::aborted() const
|
||||
{
|
||||
return p_aborted;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
bool
|
||||
test_results::skipped() const
|
||||
{
|
||||
return p_skipped;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -65,7 +84,7 @@ int
|
||||
test_results::result_code() const
|
||||
{
|
||||
return passed() ? exit_success
|
||||
: ( (p_assertions_failed > p_expected_failures || p_skipped )
|
||||
: ( (p_assertions_failed > p_expected_failures || p_skipped || p_timed_out || p_test_cases_timed_out )
|
||||
? exit_test_failure
|
||||
: exit_exception_failure );
|
||||
}
|
||||
@@ -75,6 +94,7 @@ test_results::result_code() const
|
||||
void
|
||||
test_results::operator+=( test_results const& tr )
|
||||
{
|
||||
p_test_suites.value += tr.p_test_suites;
|
||||
p_assertions_passed.value += tr.p_assertions_passed;
|
||||
p_assertions_failed.value += tr.p_assertions_failed;
|
||||
p_warnings_failed.value += tr.p_warnings_failed;
|
||||
@@ -83,6 +103,8 @@ test_results::operator+=( test_results const& tr )
|
||||
p_test_cases_failed.value += tr.p_test_cases_failed;
|
||||
p_test_cases_skipped.value += tr.p_test_cases_skipped;
|
||||
p_test_cases_aborted.value += tr.p_test_cases_aborted;
|
||||
p_test_cases_timed_out.value += tr.p_test_cases_timed_out;
|
||||
p_test_suites_timed_out.value += tr.p_test_suites_timed_out;
|
||||
p_duration_microseconds.value += tr.p_duration_microseconds;
|
||||
}
|
||||
|
||||
@@ -91,6 +113,7 @@ test_results::operator+=( test_results const& tr )
|
||||
void
|
||||
test_results::clear()
|
||||
{
|
||||
p_test_suites.value = 0;
|
||||
p_assertions_passed.value = 0;
|
||||
p_assertions_failed.value = 0;
|
||||
p_warnings_failed.value = 0;
|
||||
@@ -100,9 +123,12 @@ test_results::clear()
|
||||
p_test_cases_failed.value = 0;
|
||||
p_test_cases_skipped.value = 0;
|
||||
p_test_cases_aborted.value = 0;
|
||||
p_test_cases_timed_out.value = 0;
|
||||
p_test_suites_timed_out.value = 0;
|
||||
p_duration_microseconds.value= 0;
|
||||
p_aborted.value = false;
|
||||
p_skipped.value = false;
|
||||
p_timed_out.value = false;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -123,6 +149,10 @@ results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; re
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL( results_collector_t )
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
results_collector_t::test_start( counter_t )
|
||||
{
|
||||
@@ -159,6 +189,8 @@ public:
|
||||
else
|
||||
m_tr.p_test_cases_passed.value++;
|
||||
}
|
||||
else if( tr.p_timed_out )
|
||||
m_tr.p_test_cases_timed_out.value++;
|
||||
else if( tr.p_skipped )
|
||||
m_tr.p_test_cases_skipped.value++;
|
||||
else {
|
||||
@@ -174,6 +206,10 @@ public:
|
||||
return true;
|
||||
|
||||
m_tr += results_collector.results( ts.p_id );
|
||||
m_tr.p_test_suites.value++;
|
||||
|
||||
if( results_collector.results( ts.p_id ).p_timed_out )
|
||||
m_tr.p_test_suites_timed_out.value++;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -192,6 +228,8 @@ results_collector_t::test_unit_finish( test_unit const& tu, unsigned long elapse
|
||||
results_collect_helper ch( s_rc_impl().m_results_store[tu.p_id], tu );
|
||||
|
||||
traverse_test_tree( tu, ch );
|
||||
|
||||
s_rc_impl().m_results_store[tu.p_id].p_duration_microseconds.value = elapsed_in_microseconds;
|
||||
}
|
||||
else {
|
||||
test_results & tr = s_rc_impl().m_results_store[tu.p_id];
|
||||
@@ -213,7 +251,6 @@ void
|
||||
results_collector_t::test_unit_skipped( test_unit const& tu, const_string /*reason*/ )
|
||||
{
|
||||
test_results& tr = s_rc_impl().m_results_store[tu.p_id];
|
||||
|
||||
tr.clear();
|
||||
|
||||
tr.p_skipped.value = true;
|
||||
@@ -228,6 +265,15 @@ results_collector_t::test_unit_skipped( test_unit const& tu, const_string /*reas
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
results_collector_t::test_unit_timed_out(test_unit const& tu)
|
||||
{
|
||||
test_results& tr = s_rc_impl().m_results_store[tu.p_id];
|
||||
tr.p_timed_out.value = true;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
results_collector_t::assertion_result( unit_test::assertion_result ar )
|
||||
{
|
||||
@@ -246,11 +292,14 @@ results_collector_t::assertion_result( unit_test::assertion_result ar )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
results_collector_t::exception_caught( execution_exception const& )
|
||||
results_collector_t::exception_caught( execution_exception const& ex)
|
||||
{
|
||||
test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()];
|
||||
|
||||
tr.p_assertions_failed.value++;
|
||||
if( ex.code() == execution_exception::timeout_error ) {
|
||||
tr.p_timed_out.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
117
linx64/include/boost/test/impl/test_framework_init_observer.ipp
Normal file
117
linx64/include/boost/test/impl/test_framework_init_observer.ipp
Normal file
@@ -0,0 +1,117 @@
|
||||
// (c) Copyright Raffi Enficiaud 2017.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
//! @file
|
||||
//! An observer for monitoring the success/failure of the other observers
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_FRAMEWORK_INIT_OBSERVER_IPP_021105GER
|
||||
#define BOOST_TEST_FRAMEWORK_INIT_OBSERVER_IPP_021105GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/test_framework_init_observer.hpp>
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** framework_init_observer_t ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
namespace {
|
||||
|
||||
struct test_init_observer_check {
|
||||
bool has_failure;
|
||||
|
||||
void clear()
|
||||
{
|
||||
has_failure = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
test_init_observer_check& s_tioc_impl() { static test_init_observer_check the_inst; return the_inst; }
|
||||
|
||||
} // local namespace
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// singleton pattern
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL(framework_init_observer_t)
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
framework_init_observer_t::clear()
|
||||
{
|
||||
if(!framework::test_in_progress())
|
||||
s_tioc_impl().clear();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
framework_init_observer_t::test_start( counter_t )
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
framework_init_observer_t::assertion_result( unit_test::assertion_result ar )
|
||||
{
|
||||
test_init_observer_check& tr = s_tioc_impl();
|
||||
switch( ar ) {
|
||||
case AR_TRIGGERED: break;
|
||||
case AR_PASSED: break;
|
||||
case AR_FAILED: tr.has_failure = true; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
framework_init_observer_t::exception_caught( execution_exception const& )
|
||||
{
|
||||
test_init_observer_check& tr = s_tioc_impl();
|
||||
tr.has_failure = true;
|
||||
}
|
||||
|
||||
void
|
||||
framework_init_observer_t::test_aborted()
|
||||
{
|
||||
s_tioc_impl().has_failure = true;
|
||||
}
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
bool
|
||||
framework_init_observer_t::has_failed() const
|
||||
{
|
||||
return s_tioc_impl().has_failure;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_FRAMEWORK_INIT_OBSERVER_IPP_021105GER
|
||||
@@ -16,6 +16,7 @@
|
||||
#define BOOST_TEST_TEST_TOOLS_IPP_012205GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <boost/test/unit_test_log.hpp>
|
||||
#include <boost/test/tools/context.hpp>
|
||||
#include <boost/test/tools/output_test_stream.hpp>
|
||||
@@ -59,6 +60,13 @@ namespace std { using ::wcscmp; }
|
||||
#endif
|
||||
# endif
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
// local static variable, needed here for visibility reasons
|
||||
lazy_ostream lazy_ostream::inst = lazy_ostream();
|
||||
}}
|
||||
|
||||
namespace boost {
|
||||
namespace test_tools {
|
||||
namespace tt_detail {
|
||||
@@ -119,14 +127,6 @@ print_log_value<wchar_t const*>::operator()( std::ostream& ostr, wchar_t const*
|
||||
ostr << ( t ? t : L"null string" );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
void
|
||||
print_log_value<std::nullptr_t>::operator()( std::ostream& ostr, std::nullptr_t p )
|
||||
{
|
||||
ostr << "nullptr";
|
||||
}
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
@@ -310,8 +310,19 @@ report_assertion( assertion_result const& ar,
|
||||
{
|
||||
using namespace unit_test;
|
||||
|
||||
BOOST_TEST_I_ASSRT( framework::current_test_case_id() != INV_TEST_UNIT_ID,
|
||||
std::runtime_error( "Can't use testing tools outside of test case implementation." ) );
|
||||
if( !framework::test_in_progress() ) {
|
||||
// in case no test is in progress, we do not throw anything:
|
||||
// raising an exception here may result in raising an exception in a destructor of a global fixture
|
||||
// which will abort the process
|
||||
// We flag this as aborted instead
|
||||
|
||||
//BOOST_TEST_I_ASSRT( framework::current_test_case_id() != INV_TEST_UNIT_ID,
|
||||
// std::runtime_error( "Can't use testing tools outside of test case implementation." ) );
|
||||
|
||||
framework::test_aborted();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if( !!ar )
|
||||
tl = PASS;
|
||||
@@ -369,10 +380,11 @@ report_assertion( assertion_result const& ar,
|
||||
|
||||
case REQUIRE:
|
||||
framework::assertion_result( AR_FAILED );
|
||||
|
||||
framework::test_unit_aborted( framework::current_test_case() );
|
||||
|
||||
framework::test_unit_aborted( framework::current_test_unit() );
|
||||
BOOST_TEST_I_THROW( execution_aborted() );
|
||||
// the previous line either throws or aborts and the return below is not reached
|
||||
// return false;
|
||||
BOOST_UNREACHABLE_RETURN(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -493,7 +505,7 @@ struct output_test_stream::Impl
|
||||
|
||||
char get_char()
|
||||
{
|
||||
char res;
|
||||
char res = 0;
|
||||
do {
|
||||
m_pattern.get( res );
|
||||
} while( m_text_or_binary && res == '\r' && !m_pattern.fail() && !m_pattern.eof() );
|
||||
@@ -619,6 +631,7 @@ output_test_stream::match_pattern( bool flush_stream )
|
||||
int offset = 0;
|
||||
std::vector<char> last_elements;
|
||||
for ( std::string::size_type i = 0; static_cast<int>(i + offset) < static_cast<int>(stream_string_repr.length()); ++i ) {
|
||||
|
||||
char c = m_pimpl->get_char();
|
||||
|
||||
if( last_elements.size() <= n_chars_presuffix ) {
|
||||
@@ -698,7 +711,7 @@ output_test_stream::match_pattern( bool flush_stream )
|
||||
if( last_elements_ordered[pattern_start_index + k] == sub_str_suffix[stream_start_index + k] )
|
||||
nb_char_in_common ++;
|
||||
else
|
||||
break; // we take fully macthing substring only
|
||||
break; // we take fully matching substring only
|
||||
}
|
||||
|
||||
if( nb_char_in_common > max_nb_char_in_common ) {
|
||||
@@ -709,20 +722,32 @@ output_test_stream::match_pattern( bool flush_stream )
|
||||
}
|
||||
}
|
||||
|
||||
// indicates with more precision the location of the mismatchs in ascii arts ...
|
||||
// indicates with more precision the location of the mismatchs in "ascii arts" ...
|
||||
result.message() << " ...\n... ";
|
||||
for( std::string::size_type j = 0; j < sub_str_prefix.size(); j++) {
|
||||
result.message() << ' ';
|
||||
}
|
||||
|
||||
for( std::size_t k = 0; k < (std::max)(best_pattern_start_index, best_stream_start_index); k++ ) { // 1 is for the current char c
|
||||
result.message() << '~'; // places the first tilde at the current char that mismatches
|
||||
|
||||
for( std::size_t k = 1; k < (std::max)(best_pattern_start_index, best_stream_start_index); k++ ) { // 1 is for the current char c
|
||||
std::string s1(pretty_print_log(std::string(1, last_elements_ordered[(std::min)(k, best_pattern_start_index)])));
|
||||
std::string s2(pretty_print_log(std::string(1, sub_str_suffix[(std::min)(k, best_stream_start_index)])));
|
||||
for( int h = (std::max)(s1.size(), s2.size()); h > 0; h--)
|
||||
result.message() << "~";
|
||||
result.message() << "~";
|
||||
}
|
||||
|
||||
if( m_pimpl->m_pattern.eof() ) {
|
||||
result.message() << " (reference string shorter than current stream)";
|
||||
}
|
||||
|
||||
result.message() << "\n";
|
||||
|
||||
// no need to continue if the EOF is reached
|
||||
if( m_pimpl->m_pattern.eof() ) {
|
||||
break;
|
||||
}
|
||||
|
||||
// first char is a replicat of c, so we do not copy it.
|
||||
for(std::string::size_type counter = 0; counter < last_elements_ordered.size() - 1 ; counter++)
|
||||
last_elements[ (i + 1 + counter) % last_elements.size() ] = last_elements_ordered[counter + 1];
|
||||
|
||||
@@ -30,12 +30,10 @@
|
||||
|
||||
#include <boost/test/unit_test_parameters.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/timer.hpp>
|
||||
|
||||
// STL
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
@@ -124,7 +122,7 @@ test_unit::check_preconditions() const
|
||||
test_results const& test_rslt = unit_test::results_collector.results( dep_id );
|
||||
if( !test_rslt.passed() ) {
|
||||
test_tools::assertion_result res(false);
|
||||
res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" has failed";
|
||||
res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << (test_rslt.skipped() ? "\" was skipped":"\" has failed");
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -223,7 +221,7 @@ test_case::test_case( const_string name, const_string file_name, std::size_t lin
|
||||
//____________________________________________________________________________//
|
||||
|
||||
test_suite::test_suite( const_string name, const_string file_name, std::size_t line_num )
|
||||
: test_unit( name, file_name, line_num, static_cast<test_unit_type>(type) )
|
||||
: test_unit( ut_detail::normalize_test_case_name( name ), file_name, line_num, static_cast<test_unit_type>(type) )
|
||||
{
|
||||
framework::register_test_unit( this );
|
||||
}
|
||||
@@ -266,19 +264,80 @@ test_suite::add( test_unit_generator const& gen, unsigned timeout )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
test_suite::add( test_unit_generator const& gen, decorator::collector& decorators )
|
||||
test_suite::add( test_unit_generator const& gen, decorator::collector_t& decorators )
|
||||
{
|
||||
test_unit* tu;
|
||||
while((tu = gen.next()) != 0) {
|
||||
decorators.store_in( *tu );
|
||||
add( tu, 0 );
|
||||
}
|
||||
|
||||
decorators.reset();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
test_suite::add( boost::shared_ptr<test_unit_generator> gen_ptr, decorator::collector_t& decorators )
|
||||
{
|
||||
std::pair<boost::shared_ptr<test_unit_generator>, std::vector<decorator::base_ptr> > tmp_p(gen_ptr, decorators.get_lazy_decorators() );
|
||||
m_generators.push_back(tmp_p);
|
||||
decorators.reset();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
test_suite::generate( )
|
||||
{
|
||||
typedef std::pair<boost::shared_ptr<test_unit_generator>, std::vector<decorator::base_ptr> > element_t;
|
||||
|
||||
for(std::vector<element_t>::iterator it(m_generators.begin()), ite(m_generators.end());
|
||||
it < ite;
|
||||
++it)
|
||||
{
|
||||
test_unit* tu;
|
||||
while((tu = it->first->next()) != 0) {
|
||||
tu->p_decorators.value.insert( tu->p_decorators.value.end(), it->second.begin(), it->second.end() );
|
||||
//it->second.store_in( *tu );
|
||||
add( tu, 0 );
|
||||
}
|
||||
|
||||
}
|
||||
m_generators.clear();
|
||||
|
||||
#if 0
|
||||
test_unit* tu;
|
||||
while((tu = gen.next()) != 0) {
|
||||
decorators.store_in( *tu );
|
||||
add( tu, 0 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
test_suite::check_for_duplicate_test_cases() {
|
||||
// check for clashing names #12597
|
||||
std::set<std::string> names;
|
||||
for( test_unit_id_list::const_iterator it(m_children.begin()), ite(m_children.end());
|
||||
it < ite;
|
||||
++it) {
|
||||
std::string name = framework::get(*it, TUT_ANY).p_name;
|
||||
std::pair<std::set<std::string>::iterator, bool> ret = names.insert(name);
|
||||
BOOST_TEST_SETUP_ASSERT(ret.second,
|
||||
"test unit with name '"
|
||||
+ name
|
||||
+ std::string("' registered multiple times in the test suite '")
|
||||
+ this->p_name.value
|
||||
+ "'");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
test_suite::remove( test_unit_id id )
|
||||
{
|
||||
@@ -380,9 +439,25 @@ normalize_test_case_name( const_string name )
|
||||
|
||||
if( name[0] == '&' )
|
||||
norm_name = norm_name.substr( 1 );
|
||||
|
||||
std::replace(norm_name.begin(), norm_name.end(), ' ', '_');
|
||||
std::replace(norm_name.begin(), norm_name.end(), ':', '_');
|
||||
|
||||
// trim spaces
|
||||
std::size_t first_not_space = norm_name.find_first_not_of(' ');
|
||||
if( first_not_space ) {
|
||||
norm_name.erase(0, first_not_space);
|
||||
}
|
||||
|
||||
std::size_t last_not_space = norm_name.find_last_not_of(' ');
|
||||
if( last_not_space !=std::string::npos ) {
|
||||
norm_name.erase(last_not_space + 1);
|
||||
}
|
||||
|
||||
// sanitize all chars that might be used in runtime filters
|
||||
static const char to_replace[] = { ':', '*', '@', '+', '!', '/' };
|
||||
for(std::size_t index = 0;
|
||||
index < sizeof(to_replace)/sizeof(to_replace[0]);
|
||||
index++) {
|
||||
std::replace(norm_name.begin(), norm_name.end(), to_replace[index], '_');
|
||||
}
|
||||
|
||||
return norm_name;
|
||||
}
|
||||
@@ -393,7 +468,7 @@ normalize_test_case_name( const_string name )
|
||||
// ************** auto_test_unit_registrar ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, decorator::collector& decorators, counter_t exp_fail )
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, decorator::collector_t& decorators, counter_t exp_fail )
|
||||
{
|
||||
framework::current_auto_test_suite().add( tc, exp_fail );
|
||||
|
||||
@@ -403,7 +478,7 @@ auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, decorator::co
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector& decorators )
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector_t& decorators )
|
||||
{
|
||||
test_unit_id id = framework::current_auto_test_suite().get( ts_name );
|
||||
|
||||
@@ -426,11 +501,19 @@ auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name, const_
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector& decorators )
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector_t& decorators )
|
||||
{
|
||||
framework::current_auto_test_suite().add( tc_gen, decorators );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( boost::shared_ptr<test_unit_generator> tc_gen, decorator::collector_t& decorators )
|
||||
{
|
||||
framework::current_auto_test_suite().add( tc_gen, decorators );
|
||||
}
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( int )
|
||||
@@ -446,9 +529,49 @@ auto_test_unit_registrar::auto_test_unit_registrar( int )
|
||||
// ************** global_fixture ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
global_fixture::global_fixture()
|
||||
global_fixture::global_fixture(): registered(false)
|
||||
{
|
||||
framework::register_global_fixture( *this );
|
||||
registered = true;
|
||||
}
|
||||
|
||||
void global_fixture::unregister_from_framework() {
|
||||
// not accessing the framework singleton after deregistering -> release
|
||||
// of the observer from the framework
|
||||
if(registered) {
|
||||
framework::deregister_global_fixture( *this );
|
||||
}
|
||||
registered = false;
|
||||
}
|
||||
|
||||
global_fixture::~global_fixture()
|
||||
{
|
||||
this->unregister_from_framework();
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** global_configuration ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
global_configuration::global_configuration(): registered(false)
|
||||
{
|
||||
framework::register_observer( *this );
|
||||
registered = true;
|
||||
}
|
||||
|
||||
void global_configuration::unregister_from_framework()
|
||||
{
|
||||
// not accessing the framework singleton after deregistering -> release
|
||||
// of the observer from the framework
|
||||
if(registered) {
|
||||
framework::deregister_observer( *this );
|
||||
}
|
||||
registered = false;
|
||||
}
|
||||
|
||||
global_configuration::~global_configuration()
|
||||
{
|
||||
this->unregister_from_framework();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
@@ -159,6 +159,10 @@ unit_test_log_impl& s_log_impl() { static unit_test_log_impl the_inst; return th
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL( unit_test_log_t )
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::test_start( counter_t test_cases_amount )
|
||||
{
|
||||
@@ -168,8 +172,11 @@ unit_test_log_t::test_start( counter_t test_cases_amount )
|
||||
|
||||
current_logger_data.m_log_formatter->log_start( current_logger_data.stream(), test_cases_amount );
|
||||
|
||||
if( runtime_config::get<bool>( runtime_config::btrt_build_info ) )
|
||||
current_logger_data.m_log_formatter->log_build_info( current_logger_data.stream() );
|
||||
current_logger_data.m_log_formatter->log_build_info(
|
||||
current_logger_data.stream(),
|
||||
runtime_config::get<bool>( runtime_config::btrt_build_info ));
|
||||
|
||||
//current_logger_data.stream().flush();
|
||||
|
||||
current_logger_data.m_entry_in_progress = false;
|
||||
}
|
||||
@@ -261,6 +268,20 @@ unit_test_log_t::test_unit_aborted( test_unit const& tu )
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unit_test_log_t::test_unit_timed_out( test_unit const& tu )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() )
|
||||
*this << log::end();
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( !current_logger_data.m_enabled || current_logger_data.get_log_level() > log_test_units )
|
||||
continue;
|
||||
|
||||
current_logger_data.m_log_formatter->test_unit_timed_out(current_logger_data.stream(), tu );
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
@@ -472,14 +493,14 @@ unit_test_log_t::log_entry_context( log_level l )
|
||||
{
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_enabled ) {
|
||||
current_logger_data.m_log_formatter->log_entry_context( current_logger_data.stream(), frame );
|
||||
current_logger_data.m_log_formatter->log_entry_context( current_logger_data.stream(), l, frame );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_enabled ) {
|
||||
current_logger_data.m_log_formatter->entry_context_finish( current_logger_data.stream() );
|
||||
current_logger_data.m_log_formatter->entry_context_finish( current_logger_data.stream(), l );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,6 +544,17 @@ unit_test_log_t::set_stream( output_format log_format, std::ostream& str )
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream*
|
||||
unit_test_log_t::get_stream( output_format log_format ) const
|
||||
{
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_format == log_format) {
|
||||
return current_logger_data.m_stream;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
@@ -174,18 +175,34 @@ private:
|
||||
std::set<std::string> m_labels;
|
||||
};
|
||||
|
||||
struct framework_shutdown_helper {
|
||||
~framework_shutdown_helper() {
|
||||
try {
|
||||
framework::shutdown();
|
||||
}
|
||||
catch(...) {
|
||||
std::cerr << "Boost.Test shutdown exception caught" << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ut_detail
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** unit_test_main ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
|
||||
|
||||
int BOOST_TEST_DECL
|
||||
unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
|
||||
{
|
||||
int result_code = 0;
|
||||
|
||||
ut_detail::framework_shutdown_helper shutdown_helper;
|
||||
|
||||
BOOST_TEST_I_TRY {
|
||||
|
||||
framework::init( init_func, argc, argv );
|
||||
|
||||
if( runtime_config::get<bool>( runtime_config::btrt_wait_for_debugger ) ) {
|
||||
@@ -230,8 +247,6 @@ unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
|
||||
|
||||
framework::run();
|
||||
|
||||
results_reporter::make_report();
|
||||
|
||||
result_code = !runtime_config::get<bool>( runtime_config::btrt_result_code )
|
||||
? boost::exit_success
|
||||
: results_collector.results( framework::master_test_suite().p_id ).result_code();
|
||||
@@ -249,14 +264,17 @@ unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
|
||||
|
||||
result_code = boost::exit_exception_failure;
|
||||
}
|
||||
BOOST_TEST_I_CATCH( std::logic_error, ex ) {
|
||||
results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl;
|
||||
|
||||
result_code = boost::exit_exception_failure;
|
||||
}
|
||||
BOOST_TEST_I_CATCHALL() {
|
||||
results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl;
|
||||
|
||||
result_code = boost::exit_exception_failure;
|
||||
}
|
||||
|
||||
framework::shutdown();
|
||||
|
||||
return result_code;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,16 +29,19 @@
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
|
||||
// singleton pattern
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL(unit_test_monitor_t)
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** unit_test_monitor ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
unit_test_monitor_t::error_level
|
||||
unit_test_monitor_t::execute_and_translate( boost::function<void ()> const& func, unsigned timeout )
|
||||
unit_test_monitor_t::execute_and_translate( boost::function<void ()> const& func, unsigned long int timeout_microseconds )
|
||||
{
|
||||
BOOST_TEST_I_TRY {
|
||||
p_catch_system_errors.value = runtime_config::get<bool>( runtime_config::btrt_catch_sys_errors );
|
||||
p_timeout.value = timeout;
|
||||
p_timeout.value = timeout_microseconds;
|
||||
p_auto_start_dbg.value = runtime_config::get<bool>( runtime_config::btrt_auto_start_dbg );
|
||||
p_use_alt_stack.value = runtime_config::get<bool>( runtime_config::btrt_use_alt_stack );
|
||||
p_detect_fp_exceptions.value = runtime_config::get<bool>( runtime_config::btrt_detect_fp_except );
|
||||
@@ -47,7 +50,7 @@ unit_test_monitor_t::execute_and_translate( boost::function<void ()> const& func
|
||||
}
|
||||
BOOST_TEST_I_CATCH( execution_exception, ex ) {
|
||||
framework::exception_caught( ex );
|
||||
framework::test_unit_aborted( framework::current_test_case() );
|
||||
framework::test_unit_aborted( framework::current_test_unit() );
|
||||
|
||||
// translate execution_exception::error_code to error_level
|
||||
switch( ex.code() ) {
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/cstdlib.hpp>
|
||||
|
||||
// STL
|
||||
@@ -112,7 +111,7 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::description = "Automatically attaches debugger in case of system level failure (signal).",
|
||||
rt::env_var = "BOOST_TEST_AUTO_START_DBG",
|
||||
|
||||
rt::help = "Option " + btrt_auto_start_dbg + " specifies whether Boost.Test should attempt "
|
||||
rt::help = "Specifies whether Boost.Test should attempt "
|
||||
"to attach a debugger when fatal system error occurs. At the moment this feature "
|
||||
"is only available on a few selected platforms: Win32 and *nix. There is a "
|
||||
"default debugger configured for these platforms. You can manually configure "
|
||||
@@ -145,7 +144,7 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::option build_info( btrt_build_info, (
|
||||
rt::description = "Displays library build information.",
|
||||
rt::env_var = "BOOST_TEST_BUILD_INFO",
|
||||
rt::help = "Option " + btrt_build_info + " displays library build information, including: platform, "
|
||||
rt::help = "Displays library build information, including: platform, "
|
||||
"compiler, STL version and Boost version."
|
||||
));
|
||||
|
||||
@@ -164,7 +163,7 @@ register_parameters( rt::parameters_store& store )
|
||||
#else
|
||||
true,
|
||||
#endif
|
||||
rt::help = "If option " + btrt_catch_sys_errors + " has value no the frameworks does not attempt to catch "
|
||||
rt::help = "If option " + btrt_catch_sys_errors + " has value 'no' the frameworks does not attempt to catch "
|
||||
"asynchronous system failure events (signals on *NIX platforms or structured exceptions on Windows). "
|
||||
" Default value is "
|
||||
#ifdef BOOST_TEST_DEFAULTS_TO_CORE_DUMP
|
||||
@@ -183,9 +182,9 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::option color_output( btrt_color_output, (
|
||||
rt::description = "Enables color output of the framework log and report messages.",
|
||||
rt::env_var = "BOOST_TEST_COLOR_OUTPUT",
|
||||
rt::help = "The framework is able to produce color output on systems which supports it. "
|
||||
"To enable this behavior set this option to yes. By default the framework "
|
||||
"does not produces color output."
|
||||
rt::default_value = true,
|
||||
rt::help = "Produces color output for logs, reports and help. "
|
||||
"Defaults to true. "
|
||||
));
|
||||
|
||||
color_output.add_cla_id( "--", btrt_color_output, "=", true );
|
||||
@@ -197,7 +196,7 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::option detect_fp_except( btrt_detect_fp_except, (
|
||||
rt::description = "Enables/disables floating point exceptions traps.",
|
||||
rt::env_var = "BOOST_TEST_DETECT_FP_EXCEPTIONS",
|
||||
rt::help = "Option " + btrt_detect_fp_except + " enables/disables hardware traps for the floating "
|
||||
rt::help = "Enables/disables hardware traps for the floating "
|
||||
"point exceptions (if supported on your platfrom)."
|
||||
));
|
||||
|
||||
@@ -212,7 +211,7 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::default_value = 1L,
|
||||
rt::optional_value = 1L,
|
||||
rt::value_hint = "<alloc order number>",
|
||||
rt::help = "Parameter " + btrt_detect_mem_leaks + " enables/disables memory leaks detection. "
|
||||
rt::help = "Enables/disables memory leaks detection. "
|
||||
"This parameter has optional long integer value. The default value is 1, which "
|
||||
"enables the memory leak detection. The value 0 disables memory leak detection. "
|
||||
"Any value N greater than 1 is treated as leak allocation number and tells the "
|
||||
@@ -242,9 +241,9 @@ register_parameters( rt::parameters_store& store )
|
||||
( "DOT", OF_DOT )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_list_content + " instructs the framework to list the content "
|
||||
"of the test module instead of executing the test cases. Parameter accepts "
|
||||
"optional string value indicating the format of the output. Currently the "
|
||||
rt::help = "Lists the test suites and cases "
|
||||
"of the test module instead of executing the test cases. The format of the "
|
||||
"desired output can be passed to the command. Currently the "
|
||||
"framework supports two formats: human readable format (HRF) and dot graph "
|
||||
"format (DOT). If value is omitted HRF value is assumed."
|
||||
));
|
||||
@@ -285,7 +284,7 @@ register_parameters( rt::parameters_store& store )
|
||||
( "JUNIT", OF_JUNIT )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_log_format + " allows to set the frameowrk's log format to one "
|
||||
rt::help = "Set the frameowrk's log format to one "
|
||||
"of the formats supplied by the framework. The only acceptable values for this "
|
||||
"parameter are the names of the output formats supplied by the framework. By "
|
||||
"default the framework uses human readable format (HRF) for testing log. This "
|
||||
@@ -300,7 +299,7 @@ register_parameters( rt::parameters_store& store )
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::enum_parameter<unit_test::log_level> log_level( btrt_log_level, (
|
||||
rt::description = "Specifies log level.",
|
||||
rt::description = "Specifies the logging level of the test execution.",
|
||||
rt::env_var = "BOOST_TEST_LOG_LEVEL",
|
||||
rt::default_value = log_all_errors,
|
||||
rt::enum_values<unit_test::log_level>::value =
|
||||
@@ -333,8 +332,8 @@ register_parameters( rt::parameters_store& store )
|
||||
( "nothing" , log_nothing )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_log_level + " allows to set the framework's log level. "
|
||||
"Log level defines the verbosity of testing log produced by a testing "
|
||||
rt::help = "Set the framework's log level. "
|
||||
"The log level defines the verbosity of the testing logs produced by a test "
|
||||
"module. The verbosity ranges from a complete log, when all assertions "
|
||||
"(both successful and failing) are reported, all notifications about "
|
||||
"test units start and finish are included, to an empty log when nothing "
|
||||
@@ -348,11 +347,11 @@ register_parameters( rt::parameters_store& store )
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::parameter<std::string> log_sink( btrt_log_sink, (
|
||||
rt::description = "Specifies log sink: stdout(default), stderr or file name.",
|
||||
rt::description = "Specifies log sink: stdout (default), stderr or file name.",
|
||||
rt::env_var = "BOOST_TEST_LOG_SINK",
|
||||
rt::value_hint = "<stderr|stdout|file name>",
|
||||
rt::help = "Parameter " + btrt_log_sink + " allows to set the log sink - location "
|
||||
"where we report the log to, thus it allows to easily redirect the "
|
||||
rt::help = "Sets the log sink - the location "
|
||||
"where Boost.Test writes the logs of the test execution. It allows to easily redirect the "
|
||||
"test logs to file or standard streams. By default testing log is "
|
||||
"directed to standard output."
|
||||
));
|
||||
@@ -380,9 +379,8 @@ register_parameters( rt::parameters_store& store )
|
||||
( "XML", OF_XML )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_output_format + " combines an effect of " + btrt_report_format +
|
||||
" and " + btrt_log_format + " parameters. This parameter has higher priority "
|
||||
"than either one of them. In other words if this parameter is specified "
|
||||
rt::help = "Combines an effect of " + btrt_report_format +
|
||||
" and " + btrt_log_format + " parameters. If this parameter is specified, "
|
||||
"it overrides the value of other two parameters. This parameter does not "
|
||||
"have a default value. The only acceptable values are string names of "
|
||||
"output formats: HRF - human readable format and XML - XML formats for "
|
||||
@@ -398,9 +396,12 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::parameter<std::string,rt::REPEATABLE_PARAM> combined_logger( btrt_combined_logger, (
|
||||
rt::description = "Specifies log level and sink for one or several log format",
|
||||
rt::env_var = "BOOST_TEST_LOGGER",
|
||||
rt::value_hint = "log_format:log_level:log_sink",
|
||||
rt::help = "Parameter " + btrt_combined_logger + " allows to specify the logger type, level and sink\n"
|
||||
"in one command."
|
||||
rt::value_hint = "log_format,log_level,log_sink[:log_format,log_level,log_sink]",
|
||||
rt::help = "Specify one or more logging definition, which include the logger type, level and sink. "
|
||||
"The log format, level and sink follow the same format as for the argument '--" + btrt_log_format +
|
||||
"', '--" + btrt_log_level + "' and '--" + btrt_log_sink + "' respetively. "
|
||||
"This command can take several logging definition separated by a ':', or be repeated "
|
||||
"on the command line."
|
||||
));
|
||||
|
||||
combined_logger.add_cla_id( "--", btrt_combined_logger, "=" );
|
||||
@@ -415,14 +416,14 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::default_value = 0U,
|
||||
rt::optional_value = 1U,
|
||||
rt::value_hint = "<seed>",
|
||||
rt::help = "Parameter " + btrt_random_seed + " instructs the framework to execute the "
|
||||
"test cases in random order. This parameter accepts optional unsigned "
|
||||
"integer argument. By default test cases are executed in some specific "
|
||||
"order defined by order of test units in test files and dependency between "
|
||||
"test units. If parameter is specified without the argument value testing "
|
||||
rt::help = "Instructs the framework to execute the "
|
||||
"test cases in random order. This parameter accepts an optional unsigned "
|
||||
"integer argument. If parameter is specified without the argument value testing "
|
||||
"order is randomized based on current time. Alternatively you can specify "
|
||||
"any positive value greater than 1 and it will be used as random seed for "
|
||||
"the run."
|
||||
"the run. "
|
||||
"By default, the test cases are executed in an "
|
||||
"order defined by their declaration and the optional dependencies among the test units."
|
||||
));
|
||||
|
||||
random_seed.add_cla_id( "--", btrt_random_seed, "=" );
|
||||
@@ -431,7 +432,7 @@ register_parameters( rt::parameters_store& store )
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::enum_parameter<unit_test::output_format> report_format( btrt_report_format, (
|
||||
rt::description = "Specifies report format.",
|
||||
rt::description = "Specifies the test report format.",
|
||||
rt::env_var = "BOOST_TEST_REPORT_FORMAT",
|
||||
rt::default_value = OF_CLF,
|
||||
rt::enum_values<unit_test::output_format>::value =
|
||||
@@ -448,7 +449,7 @@ register_parameters( rt::parameters_store& store )
|
||||
( "XML", OF_XML )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_report_format + " allows to set the framework's report format "
|
||||
rt::help = "Set the framework's report format "
|
||||
"to one of the formats supplied by the framework. The only acceptable values "
|
||||
"for this parameter are the names of the output formats. By default the framework "
|
||||
"uses human readable format (HRF) for results reporting. Alternatively you can "
|
||||
@@ -463,7 +464,7 @@ register_parameters( rt::parameters_store& store )
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::enum_parameter<unit_test::report_level> report_level( btrt_report_level, (
|
||||
rt::description = "Specifies report level.",
|
||||
rt::description = "Specifies test report level.",
|
||||
rt::env_var = "BOOST_TEST_REPORT_LEVEL",
|
||||
rt::default_value = CONFIRMATION_REPORT,
|
||||
rt::enum_values<unit_test::report_level>::value =
|
||||
@@ -482,9 +483,9 @@ register_parameters( rt::parameters_store& store )
|
||||
( "no", NO_REPORT )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_report_level + " allows to set the verbosity level of the "
|
||||
"testing result report generated by the framework. Use value 'no' to "
|
||||
"eliminate the results report completely."
|
||||
rt::help = "Set the verbosity level of the "
|
||||
"result report generated by the testing framework. Use value 'no' to "
|
||||
"disable the results report completely."
|
||||
));
|
||||
|
||||
report_level.add_cla_id( "--", btrt_report_level, "=" );
|
||||
@@ -512,10 +513,10 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::description = "Specifies report sink: stderr(default), stdout or file name.",
|
||||
rt::env_var = "BOOST_TEST_REPORT_SINK",
|
||||
rt::value_hint = "<stderr|stdout|file name>",
|
||||
rt::help = "Parameter " + btrt_report_sink + " allows to set the result report sink - "
|
||||
"the location where the framework writes the result report to, thus it "
|
||||
"allows to easily redirect the result report to a file or a standard "
|
||||
"stream. By default the testing result report is directed to the "
|
||||
rt::help = "Sets the result report sink - "
|
||||
"the location where the framework writes the result report to. "
|
||||
"The sink may be a a file or a standard "
|
||||
"stream. The default is 'stderr': the "
|
||||
"standard error stream."
|
||||
));
|
||||
|
||||
@@ -541,13 +542,13 @@ register_parameters( rt::parameters_store& store )
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::parameter<std::string,rt::REPEATABLE_PARAM> tests_to_run( btrt_run_filters, (
|
||||
rt::description = "Filters, which test units to include or exclude from test module execution.",
|
||||
rt::description = "Filters which tests to execute.",
|
||||
rt::env_var = "BOOST_TEST_RUN_FILTERS",
|
||||
rt::value_hint = "<test unit filter>",
|
||||
rt::help = "Parameter " + btrt_run_filters + " allows to filter which test units to execute during "
|
||||
"testing. The framework supports both 'selection filters', which allow to select "
|
||||
rt::help = "Filters which test units to execute. "
|
||||
"The framework supports both 'selection filters', which allow to select "
|
||||
"which test units to enable from the set of available test units, and 'disabler "
|
||||
"filters', which allow to disable some test units. The __UTF__ also supports "
|
||||
"filters', which allow to disable some test units. Boost.test also supports "
|
||||
"enabling/disabling test units at compile time. These settings identify the default "
|
||||
"set of test units to run. Parameter " + btrt_run_filters + " is used to change this default. "
|
||||
"This parameter is repeatable, so you can specify more than one filter if necessary."
|
||||
@@ -576,8 +577,8 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::option show_progress( btrt_show_progress, (
|
||||
rt::description = "Turns on progress display.",
|
||||
rt::env_var = "BOOST_TEST_SHOW_PROGRESS",
|
||||
rt::help = "Parameter " + btrt_show_progress + " instructs the framework to display test progress "
|
||||
"information. By default the test progress is not shown."
|
||||
rt::help = "Instructs the framework to display the progress of the tests. "
|
||||
"This feature is turned off by default."
|
||||
));
|
||||
|
||||
show_progress.add_cla_id( "--", btrt_show_progress, "=" );
|
||||
@@ -590,9 +591,9 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::description = "Turns on/off usage of an alternative stack for signal handling.",
|
||||
rt::env_var = "BOOST_TEST_USE_ALT_STACK",
|
||||
rt::default_value = true,
|
||||
rt::help = "Parameter " + btrt_use_alt_stack + " instructs the framework to use alternative "
|
||||
"stack for signals processing, on platforms where they are supported. The feature "
|
||||
"is enabled by default, but can be disabled using this parameter."
|
||||
rt::help = "Instructs the framework to use an alternative "
|
||||
"stack for operating system's signals handling (on platforms where this is supported). "
|
||||
"The feature is enabled by default, but can be disabled using this command line switch."
|
||||
));
|
||||
|
||||
use_alt_stack.add_cla_id( "--", btrt_use_alt_stack, "=", true );
|
||||
@@ -603,9 +604,9 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::option wait_for_debugger( btrt_wait_for_debugger, (
|
||||
rt::description = "Forces test module to wait for button to be pressed before starting test run.",
|
||||
rt::env_var = "BOOST_TEST_WAIT_FOR_DEBUGGER",
|
||||
rt::help = "Parameter " + btrt_wait_for_debugger + " instructs the framework to pause before starting "
|
||||
"test units execution, so that you can attach a debugger to running test module. By "
|
||||
"default this parameters turned off."
|
||||
rt::help = "Instructs the framework to pause before starting "
|
||||
"test units execution, so that you can attach a debugger to the test module process. "
|
||||
"This feature is turned off by default."
|
||||
));
|
||||
|
||||
wait_for_debugger.add_cla_id( "--", btrt_wait_for_debugger, "=" );
|
||||
@@ -618,10 +619,10 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::description = "Help for framework parameters.",
|
||||
rt::optional_value = std::string(),
|
||||
rt::value_hint = "<parameter name>",
|
||||
rt::help = "Parameter " + btrt_help + " displays help on the framework's parameters. "
|
||||
rt::help = "Displays help on the framework's parameters. "
|
||||
"The parameter accepts an optional argument value. If present, an argument value is "
|
||||
"interpreted as a parameter name (name guessing works as well, so for example "
|
||||
"--help=rand displays help on the parameter random). If the parameter name is unknown "
|
||||
"'--help=rand' displays help on the parameter 'random'). If the parameter name is unknown "
|
||||
"or ambiguous error is reported. If argument value is absent, a summary of all "
|
||||
"framework's parameter is displayed."
|
||||
));
|
||||
@@ -675,17 +676,26 @@ init( int& argc, char** argv )
|
||||
// Set arguments to default values if defined and perform all the validations
|
||||
rt::finalize_arguments( s_parameters_store, s_arguments_store );
|
||||
|
||||
// check if colorized output is enabled
|
||||
bool use_color = true;
|
||||
if( s_arguments_store.has(btrt_color_output ) ) {
|
||||
use_color = runtime_config::get<bool>(runtime_config::btrt_color_output);
|
||||
}
|
||||
|
||||
// Report help if requested
|
||||
if( runtime_config::get<bool>( btrt_version ) ) {
|
||||
parser->version( std::cerr );
|
||||
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
|
||||
}
|
||||
else if( runtime_config::get<bool>( btrt_usage ) ) {
|
||||
parser->usage( std::cerr );
|
||||
parser->usage( std::cerr, runtime::cstring(), use_color );
|
||||
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
|
||||
}
|
||||
else if( s_arguments_store.has( btrt_help ) ) {
|
||||
parser->help( std::cerr, s_parameters_store, runtime_config::get<std::string>( btrt_help ) );
|
||||
parser->help(std::cerr,
|
||||
s_parameters_store,
|
||||
runtime_config::get<std::string>( btrt_help ),
|
||||
use_color );
|
||||
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -63,16 +63,18 @@ xml_log_formatter::log_finish( std::ostream& ostr )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
xml_log_formatter::log_build_info( std::ostream& ostr )
|
||||
xml_log_formatter::log_build_info( std::ostream& ostr, bool log_build_info )
|
||||
{
|
||||
ostr << "<BuildInfo"
|
||||
<< " platform" << utils::attr_value() << BOOST_PLATFORM
|
||||
<< " compiler" << utils::attr_value() << BOOST_COMPILER
|
||||
<< " stl" << utils::attr_value() << BOOST_STDLIB
|
||||
<< " boost=\"" << BOOST_VERSION/100000 << "."
|
||||
<< BOOST_VERSION/100 % 1000 << "."
|
||||
<< BOOST_VERSION % 100 << '\"'
|
||||
<< "/>";
|
||||
if( log_build_info ) {
|
||||
ostr << "<BuildInfo"
|
||||
<< " platform" << utils::attr_value() << BOOST_PLATFORM
|
||||
<< " compiler" << utils::attr_value() << BOOST_COMPILER
|
||||
<< " stl" << utils::attr_value() << BOOST_STDLIB
|
||||
<< " boost=\"" << BOOST_VERSION/100000 << "."
|
||||
<< BOOST_VERSION/100 % 1000 << "."
|
||||
<< BOOST_VERSION % 100 << '\"'
|
||||
<< "/>";
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -199,7 +201,7 @@ xml_log_formatter::entry_context_start( std::ostream& ostr, log_level )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
xml_log_formatter::entry_context_finish( std::ostream& ostr )
|
||||
xml_log_formatter::entry_context_finish( std::ostream& ostr, log_level )
|
||||
{
|
||||
ostr << BOOST_TEST_L( "</Context>" );
|
||||
}
|
||||
@@ -207,7 +209,7 @@ xml_log_formatter::entry_context_finish( std::ostream& ostr )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
xml_log_formatter::log_entry_context( std::ostream& ostr, const_string context_descr )
|
||||
xml_log_formatter::log_entry_context( std::ostream& ostr, log_level, const_string context_descr )
|
||||
{
|
||||
ostr << BOOST_TEST_L( "<Frame>" ) << utils::cdata() << context_descr << BOOST_TEST_L( "</Frame>" );
|
||||
}
|
||||
|
||||
@@ -59,6 +59,8 @@ xml_report_formatter::test_unit_report_start( test_unit const& tu, std::ostream&
|
||||
descr = "passed";
|
||||
else if( tr.p_skipped )
|
||||
descr = "skipped";
|
||||
else if( tr.p_timed_out )
|
||||
descr = "timed-out";
|
||||
else if( tr.p_aborted )
|
||||
descr = "aborted";
|
||||
else
|
||||
@@ -70,14 +72,18 @@ xml_report_formatter::test_unit_report_start( test_unit const& tu, std::ostream&
|
||||
<< " assertions_passed" << utils::attr_value() << tr.p_assertions_passed
|
||||
<< " assertions_failed" << utils::attr_value() << tr.p_assertions_failed
|
||||
<< " warnings_failed" << utils::attr_value() << tr.p_warnings_failed
|
||||
<< " expected_failures" << utils::attr_value() << tr.p_expected_failures;
|
||||
<< " expected_failures" << utils::attr_value() << tr.p_expected_failures
|
||||
;
|
||||
|
||||
if( tu.p_type == TUT_SUITE ) {
|
||||
ostr << " test_cases_passed" << utils::attr_value() << tr.p_test_cases_passed
|
||||
<< " test_cases_passed_with_warnings" << utils::attr_value() << tr.p_test_cases_warned
|
||||
<< " test_cases_failed" << utils::attr_value() << tr.p_test_cases_failed
|
||||
<< " test_cases_skipped" << utils::attr_value() << tr.p_test_cases_skipped
|
||||
<< " test_cases_aborted" << utils::attr_value() << tr.p_test_cases_aborted;
|
||||
<< " test_cases_aborted" << utils::attr_value() << tr.p_test_cases_aborted
|
||||
<< " test_cases_timed_out" << utils::attr_value() << tr.p_test_cases_timed_out
|
||||
<< " test_suites_timed_out"<< utils::attr_value() << tr.p_test_suites_timed_out
|
||||
;
|
||||
}
|
||||
|
||||
ostr << '>';
|
||||
|
||||
Reference in New Issue
Block a user