summaryrefslogtreecommitdiff
path: root/boost/test
diff options
context:
space:
mode:
Diffstat (limited to 'boost/test')
-rw-r--r--boost/test/data/monomorphic/delayed.hpp11
-rw-r--r--boost/test/data/monomorphic/generators/keywords.hpp6
-rw-r--r--boost/test/data/monomorphic/initializer_list.hpp2
-rw-r--r--boost/test/data/monomorphic/singleton.hpp4
-rw-r--r--boost/test/data/test_case.hpp21
-rw-r--r--boost/test/detail/config.hpp23
-rw-r--r--boost/test/detail/fwd_decl.hpp1
-rw-r--r--boost/test/detail/global_typedef.hpp14
-rw-r--r--boost/test/detail/log_level.hpp4
-rw-r--r--boost/test/detail/workaround.hpp56
-rw-r--r--boost/test/execution_monitor.hpp9
-rw-r--r--boost/test/framework.hpp4
-rw-r--r--boost/test/impl/compiler_log_formatter.ipp16
-rw-r--r--boost/test/impl/debug.ipp18
-rw-r--r--boost/test/impl/decorator.ipp46
-rw-r--r--boost/test/impl/execution_monitor.ipp132
-rw-r--r--boost/test/impl/framework.ipp117
-rw-r--r--boost/test/impl/junit_log_formatter.ipp51
-rw-r--r--boost/test/impl/plain_report_formatter.ipp13
-rw-r--r--boost/test/impl/results_collector.ipp37
-rw-r--r--boost/test/impl/test_tools.ipp12
-rw-r--r--boost/test/impl/test_tree.ipp32
-rw-r--r--boost/test/impl/unit_test_log.ipp19
-rw-r--r--boost/test/impl/unit_test_main.ipp1
-rw-r--r--boost/test/impl/unit_test_monitor.ipp4
-rw-r--r--boost/test/impl/xml_log_formatter.ipp20
-rw-r--r--boost/test/impl/xml_report_formatter.ipp10
-rw-r--r--boost/test/minimal.hpp3
-rw-r--r--boost/test/output/compiler_log_formatter.hpp2
-rw-r--r--boost/test/output/junit_log_formatter.hpp3
-rw-r--r--boost/test/output/xml_log_formatter.hpp2
-rw-r--r--boost/test/results_collector.hpp5
-rw-r--r--boost/test/tools/context.hpp37
-rw-r--r--boost/test/tools/detail/print_helper.hpp1
-rw-r--r--boost/test/tools/fpc_op.hpp17
-rw-r--r--boost/test/tools/old/impl.hpp2
-rw-r--r--boost/test/tools/old/interface.hpp10
-rw-r--r--boost/test/tree/decorator.hpp39
-rw-r--r--boost/test/tree/global_fixture.hpp16
-rw-r--r--boost/test/tree/observer.hpp16
-rw-r--r--boost/test/tree/test_case_template.hpp59
-rw-r--r--boost/test/tree/test_unit.hpp6
-rw-r--r--boost/test/unit_test_log.hpp1
-rw-r--r--boost/test/unit_test_log_formatter.hpp9
-rw-r--r--boost/test/unit_test_monitor.hpp3
-rw-r--r--boost/test/unit_test_suite.hpp15
-rw-r--r--boost/test/utils/basic_cstring/basic_cstring.hpp9
-rw-r--r--boost/test/utils/basic_cstring/basic_cstring_fwd.hpp5
-rw-r--r--boost/test/utils/foreach.hpp1
-rw-r--r--boost/test/utils/lazy_ostream.hpp5
-rw-r--r--boost/test/utils/rtti.hpp5
-rw-r--r--boost/test/utils/runtime/cla/parser.hpp40
-rw-r--r--boost/test/utils/runtime/errors.hpp6
-rw-r--r--boost/test/utils/setcolor.hpp10
-rw-r--r--boost/test/utils/timer.hpp164
55 files changed, 856 insertions, 318 deletions
diff --git a/boost/test/data/monomorphic/delayed.hpp b/boost/test/data/monomorphic/delayed.hpp
index 43ab15e7e4..9b513c144b 100644
--- a/boost/test/data/monomorphic/delayed.hpp
+++ b/boost/test/data/monomorphic/delayed.hpp
@@ -50,7 +50,6 @@ class delayed_dataset
public:
enum { arity = dataset_t::arity };
using iterator = decltype(std::declval<dataset_t>().begin());
- using sample = typename dataset_t::sample;
delayed_dataset(Args... args)
: m_args(std::make_tuple(std::forward<Args>(args)...))
@@ -74,10 +73,10 @@ public:
private:
dataset_t& get() const {
- if(!m_dataset) {
- m_dataset = create(boost::unit_test::data::index_sequence_for<Args...>());
- }
- return *m_dataset;
+ if(!m_dataset) {
+ m_dataset = create(boost::unit_test::data::index_sequence_for<Args...>());
+ }
+ return *m_dataset;
}
template<std::size_t... I>
@@ -101,6 +100,8 @@ struct is_dataset< delayed_dataset<dataset_t, Args...> > : boost::mpl::true_ {};
} // namespace monomorphic
+
+//! Delayed dataset instanciation
template<class dataset_t, class ...Args>
inline typename std::enable_if<
monomorphic::is_dataset< dataset_t >::value,
diff --git a/boost/test/data/monomorphic/generators/keywords.hpp b/boost/test/data/monomorphic/generators/keywords.hpp
index de6a4e89e5..7dd6f8ae9a 100644
--- a/boost/test/data/monomorphic/generators/keywords.hpp
+++ b/boost/test/data/monomorphic/generators/keywords.hpp
@@ -25,9 +25,9 @@ namespace unit_test {
namespace data {
namespace {
-nfp::keyword<struct begin_t> begin;
-nfp::keyword<struct end_t> end;
-nfp::keyword<struct step_t> step;
+nfp::keyword<struct begin_t> begin BOOST_ATTRIBUTE_UNUSED;
+nfp::keyword<struct end_t> end BOOST_ATTRIBUTE_UNUSED;
+nfp::keyword<struct step_t> step BOOST_ATTRIBUTE_UNUSED;
} // local namespace
} // namespace data
diff --git a/boost/test/data/monomorphic/initializer_list.hpp b/boost/test/data/monomorphic/initializer_list.hpp
index 0a8a88ab0b..f46a085aee 100644
--- a/boost/test/data/monomorphic/initializer_list.hpp
+++ b/boost/test/data/monomorphic/initializer_list.hpp
@@ -41,8 +41,6 @@ namespace monomorphic {
template<typename T>
class init_list {
public:
- typedef T sample;
-
enum { arity = 1 };
typedef typename std::vector<T>::const_iterator iterator;
diff --git a/boost/test/data/monomorphic/singleton.hpp b/boost/test/data/monomorphic/singleton.hpp
index b0abd0eabb..6b9311590a 100644
--- a/boost/test/data/monomorphic/singleton.hpp
+++ b/boost/test/data/monomorphic/singleton.hpp
@@ -32,9 +32,11 @@ namespace monomorphic {
/// Models a single element data set
template<typename T>
class singleton {
-public:
+private:
typedef typename boost::decay<T>::type sample;
+public:
+
enum { arity = 1 };
struct iterator {
diff --git a/boost/test/data/test_case.hpp b/boost/test/data/test_case.hpp
index 2b3e7e4c61..0c0f2156a0 100644
--- a/boost/test/data/test_case.hpp
+++ b/boost/test/data/test_case.hpp
@@ -252,20 +252,29 @@ struct BOOST_PP_CAT(test_name, case) : public F { \
template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
static void test_method( BOOST_DATA_TEST_CASE_PARAMS( params ) ) \
{ \
- BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture entry.");\
- BOOST_PP_CAT(test_name, case) t; \
- BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry."); \
BOOST_TEST_CONTEXT( "" \
BOOST_PP_SEQ_FOR_EACH(BOOST_DATA_TEST_CONTEXT, _, params)) \
- t._impl(BOOST_PP_SEQ_ENUM(params)); \
- BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit."); \
+ { \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture ctor");\
+ BOOST_PP_CAT(test_name, case) t; \
+ BOOST_TEST_CHECKPOINT('"' \
+ << #test_name << "\" fixture setup"); \
+ boost::unit_test::setup_conditional(t); \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" test entry"); \
+ t._impl(BOOST_PP_SEQ_ENUM(params)); \
+ BOOST_TEST_CHECKPOINT('"' \
+ << #test_name << "\" fixture teardown"); \
+ boost::unit_test::teardown_conditional(t); \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture dtor");\
+ } \
} \
private: \
template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
void _impl(BOOST_DATA_TEST_CASE_PARAMS( params )); \
}; \
\
-BOOST_AUTO_TEST_SUITE( test_name ) \
+BOOST_AUTO_TEST_SUITE( test_name, \
+ *boost::unit_test::decorator::stack_decorator()) \
\
BOOST_AUTO_TU_REGISTRAR( BOOST_PP_CAT(test_name, case) )( \
boost::unit_test::data::ds_detail::make_test_case_gen< \
diff --git a/boost/test/detail/config.hpp b/boost/test/detail/config.hpp
index db9b5d2b92..bcdd857613 100644
--- a/boost/test/detail/config.hpp
+++ b/boost/test/detail/config.hpp
@@ -78,10 +78,27 @@ class type_info;
//____________________________________________________________________________//
+// Sun compiler does not support visibility on enums
+#if defined(__SUNPRO_CC)
+#define BOOST_TEST_ENUM_SYMBOL_VISIBLE
+#else
+#define BOOST_TEST_ENUM_SYMBOL_VISIBLE BOOST_SYMBOL_VISIBLE
+#endif
+
+//____________________________________________________________________________//
+
#if defined(BOOST_ALL_DYN_LINK) && !defined(BOOST_TEST_DYN_LINK)
# define BOOST_TEST_DYN_LINK
#endif
+// in case any of the define from cmake/b2 is set
+#if !defined(BOOST_TEST_DYN_LINK) \
+ && (defined(BOOST_UNIT_TEST_FRAMEWORK_DYN_LINK) \
+ || defined(BOOST_TEST_EXEC_MONITOR_DYN_LINK) \
+ || defined(BOOST_PRG_EXEC_MONITOR_DYN_LINK) )
+# define BOOST_TEST_DYN_LINK
+#endif
+
#if defined(BOOST_TEST_INCLUDED)
# undef BOOST_TEST_DYN_LINK
#endif
@@ -90,12 +107,12 @@ class type_info;
# define BOOST_TEST_ALTERNATIVE_INIT_API
# ifdef BOOST_TEST_SOURCE
-# define BOOST_TEST_DECL BOOST_SYMBOL_EXPORT
+# define BOOST_TEST_DECL BOOST_SYMBOL_EXPORT BOOST_SYMBOL_VISIBLE
# else
-# define BOOST_TEST_DECL BOOST_SYMBOL_IMPORT
+# define BOOST_TEST_DECL BOOST_SYMBOL_IMPORT BOOST_SYMBOL_VISIBLE
# endif // BOOST_TEST_SOURCE
#else
-# define BOOST_TEST_DECL
+# define BOOST_TEST_DECL BOOST_SYMBOL_VISIBLE
#endif
#if !defined(BOOST_TEST_MAIN) && defined(BOOST_AUTO_TEST_MAIN)
diff --git a/boost/test/detail/fwd_decl.hpp b/boost/test/detail/fwd_decl.hpp
index d5c97fb706..3d6b55a139 100644
--- a/boost/test/detail/fwd_decl.hpp
+++ b/boost/test/detail/fwd_decl.hpp
@@ -27,6 +27,7 @@ class master_test_suite_t;
class test_tree_visitor;
class test_observer;
class test_unit_fixture;
+class global_fixture;
// singletons
class unit_test_monitor_t;
diff --git a/boost/test/detail/global_typedef.hpp b/boost/test/detail/global_typedef.hpp
index ae932a4514..5e6f960737 100644
--- a/boost/test/detail/global_typedef.hpp
+++ b/boost/test/detail/global_typedef.hpp
@@ -13,7 +13,6 @@
#define BOOST_TEST_GLOBAL_TYPEDEF_HPP_021005GER
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
-#include <boost/test/detail/workaround.hpp>
#define BOOST_TEST_L( s ) ::boost::unit_test::const_string( s, sizeof( s ) - 1 )
#define BOOST_TEST_STRINGIZE( s ) BOOST_TEST_L( BOOST_STRINGIZE( s ) )
@@ -106,16 +105,21 @@ T static_constant<T>::value;
// BOOST_TEST_SINGLETON_CONS_IMPL should be in only one translation unit. The
// global instance should be declared by BOOST_TEST_SINGLETON_INST.
-#define BOOST_TEST_SINGLETON_CONS( type ) \
+#define BOOST_TEST_SINGLETON_CONS_NO_CTOR( type ) \
public: \
static type& instance(); \
private: \
BOOST_DELETED_FUNCTION(type(type const&)) \
BOOST_DELETED_FUNCTION(type& operator=(type const&)) \
- BOOST_DEFAULTED_FUNCTION(type(), {}) \
BOOST_DEFAULTED_FUNCTION(~type(), {}) \
/**/
+#define BOOST_TEST_SINGLETON_CONS( type ) \
+ BOOST_TEST_SINGLETON_CONS_NO_CTOR(type) \
+private: \
+ BOOST_DEFAULTED_FUNCTION(type(), {}) \
+/**/
+
#define BOOST_TEST_SINGLETON_CONS_IMPL( type ) \
type& type::instance() { \
static type the_inst; return the_inst; \
@@ -126,12 +130,12 @@ private: \
#if defined(__APPLE_CC__) && defined(__GNUC__) && __GNUC__ < 4
#define BOOST_TEST_SINGLETON_INST( inst ) \
-static BOOST_JOIN( inst, _t)& inst = BOOST_JOIN (inst, _t)::instance();
+static BOOST_JOIN( inst, _t)& inst BOOST_ATTRIBUTE_UNUSED = BOOST_JOIN (inst, _t)::instance();
#else
#define BOOST_TEST_SINGLETON_INST( inst ) \
-namespace { BOOST_JOIN( inst, _t)& inst = BOOST_JOIN( inst, _t)::instance(); }
+namespace { BOOST_JOIN( inst, _t)& inst BOOST_ATTRIBUTE_UNUSED = BOOST_JOIN( inst, _t)::instance(); }
#endif
diff --git a/boost/test/detail/log_level.hpp b/boost/test/detail/log_level.hpp
index abdecea7ec..d391e103d1 100644
--- a/boost/test/detail/log_level.hpp
+++ b/boost/test/detail/log_level.hpp
@@ -12,6 +12,8 @@
#ifndef BOOST_TEST_LOG_LEVEL_HPP_011605GER
#define BOOST_TEST_LOG_LEVEL_HPP_011605GER
+#include <boost/test/detail/config.hpp>
+
namespace boost {
namespace unit_test {
@@ -20,7 +22,7 @@ namespace unit_test {
// ************************************************************************** //
// each log level includes all subsequent higher loging levels
-enum log_level {
+enum BOOST_TEST_ENUM_SYMBOL_VISIBLE log_level {
invalid_log_level = -1,
log_successful_tests = 0,
log_test_units = 1,
diff --git a/boost/test/detail/workaround.hpp b/boost/test/detail/workaround.hpp
deleted file mode 100644
index 4ba3a7e934..0000000000
--- a/boost/test/detail/workaround.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-// (C) Copyright Gennadiy Rozental 2001.
-// 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
-//!@brief contains mics. workarounds
-// ***************************************************************************
-
-#ifndef BOOST_TEST_WORKAROUND_HPP_021005GER
-#define BOOST_TEST_WORKAROUND_HPP_021005GER
-
-// Boost
-#include <boost/config.hpp> // compilers workarounds and std::ptrdiff_t
-
-// STL
-#include <iterator> // for std::distance
-
-#include <boost/test/detail/suppress_warnings.hpp>
-
-//____________________________________________________________________________//
-
-namespace boost {
-namespace unit_test {
-namespace ut_detail {
-
-#ifdef BOOST_NO_STD_DISTANCE
-template <class T>
-std::ptrdiff_t distance( T const& x_, T const& y_ )
-{
- std::ptrdiff_t res = 0;
-
- std::distance( x_, y_, res );
-
- return res;
-}
-
-//____________________________________________________________________________//
-
-#else
-using std::distance;
-#endif
-
-template <class T> inline void ignore_unused_variable_warning(const T&) {}
-
-} // namespace ut_detail
-} // namespace unit_test
-} // namespace boost
-
-//____________________________________________________________________________//
-
-#include <boost/test/detail/enable_warnings.hpp>
-
-#endif // BOOST_TEST_WORKAROUND_HPP_021005GER
diff --git a/boost/test/execution_monitor.hpp b/boost/test/execution_monitor.hpp
index bda732b980..25e0129edd 100644
--- a/boost/test/execution_monitor.hpp
+++ b/boost/test/execution_monitor.hpp
@@ -111,7 +111,8 @@ namespace boost {
///
/// @section DesignRationale Design Rationale
///
-/// The Execution Monitor design assumes that it can be used when no (or almost no) memory available. Also the Execution Monitor is intended to be portable to as many platforms as possible.
+/// The Execution Monitor design assumes that it can be used when no (or almost no) memory available. Also the Execution Monitor
+/// is intended to be portable to as many platforms as possible.
///
/// @section UserGuide User's guide
/// The Execution Monitor is designed to solve the problem of executing potentially dangerous function that may result in any number of error conditions,
@@ -337,9 +338,9 @@ public:
/// Specifies the seconds that elapse before a timer_error occurs.
///
- /// The @em p_timeout property is an integer timeout (in seconds) for monitored function execution. Use this parameter to monitor code with possible deadlocks
- /// or indefinite loops. This feature is only available for some operating systems (not yet Microsoft Windows).
- unit_test::readwrite_property<unsigned> p_timeout;
+ /// The @em p_timeout property is an integer timeout (in microseconds) for monitored function execution. Use this parameter to monitor code with possible deadlocks
+ /// or infinite loops. This feature is only available for some operating systems (not yet Microsoft Windows).
+ unit_test::readwrite_property<unsigned long int> p_timeout;
/// Should monitor use alternative stack for the signal catching.
///
diff --git a/boost/test/framework.hpp b/boost/test/framework.hpp
index 2f446791aa..dd0756f9d4 100644
--- a/boost/test/framework.hpp
+++ b/boost/test/framework.hpp
@@ -143,13 +143,13 @@ BOOST_TEST_DECL void deregister_observer( test_observer& to );
/// any other tests finished.
/// Test unit fixture lifetime should exceed the testing execution timeframe
/// @param[in] tuf fixture to add
-BOOST_TEST_DECL void register_global_fixture( test_unit_fixture& tuf );
+BOOST_TEST_DECL void register_global_fixture( global_fixture& tuf );
/// Removes a test global fixture from the framework
///
/// Test unit fixture lifetime should exceed the testing execution timeframe
/// @param[in] tuf fixture to remove
-BOOST_TEST_DECL void deregister_global_fixture( test_unit_fixture& tuf );
+BOOST_TEST_DECL void deregister_global_fixture( global_fixture& tuf );
/// @}
/// @name Assertion/uncaught exception context support
diff --git a/boost/test/impl/compiler_log_formatter.ipp b/boost/test/impl/compiler_log_formatter.ipp
index cd7de1fe76..1b2645ba12 100644
--- a/boost/test/impl/compiler_log_formatter.ipp
+++ b/boost/test/impl/compiler_log_formatter.ipp
@@ -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;
+ }
}
//____________________________________________________________________________//
diff --git a/boost/test/impl/debug.ipp b/boost/test/impl/debug.ipp
index a5e5f6da06..bee956c1cb 100644
--- a/boost/test/impl/debug.ipp
+++ b/boost/test/impl/debug.ipp
@@ -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;
@@ -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
-
diff --git a/boost/test/impl/decorator.ipp b/boost/test/impl/decorator.ipp
index e4bf11ee26..ac6cc7e278 100644
--- a/boost/test/impl/decorator.ipp
+++ b/boost/test/impl/decorator.ipp
@@ -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
// ***************************************************************************
@@ -45,7 +41,7 @@ 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;
}
@@ -55,7 +51,10 @@ collector_t::operator*( base const& d )
void
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() );
}
//____________________________________________________________________________//
@@ -63,7 +62,20 @@ collector_t::store_in( test_unit& tu )
void
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>());
}
//____________________________________________________________________________//
@@ -71,7 +83,7 @@ collector_t::reset()
std::vector<base_ptr>
collector_t::get_lazy_decorators() const
{
- return m_tu_decorators;
+ return *m_tu_decorators_stack.begin();
}
//____________________________________________________________________________//
@@ -87,6 +99,24 @@ base::operator*() const
}
// ************************************************************************** //
+// ************** 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
+}
+
+// ************************************************************************** //
// ************** decorator::label ************** //
// ************************************************************************** //
diff --git a/boost/test/impl/execution_monitor.ipp b/boost/test/impl/execution_monitor.ipp
index 9b7c5965b4..2c2cd3871f 100644
--- a/boost/test/impl/execution_monitor.ipp
+++ b/boost/test/impl/execution_monitor.ipp
@@ -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>
@@ -48,24 +47,19 @@
#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>
-using std::va_list;
-#endif
-
-// to use vsnprintf
-#if defined(__QNXNTO__) || defined(__VXWORKS__)
-# include <stdio.h>
+#if defined(__SUNPRO_CC) || defined(__SunOS) || defined(__QNXNTO__) || defined(__VXWORKS__)
using std::va_list;
#endif
@@ -74,6 +68,11 @@ using std::va_list;
#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))
@@ -107,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)
@@ -215,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) )
@@ -369,16 +373,16 @@ system_signal_exception::report() const
switch( m_sig_info->si_code ) {
#ifdef __VXWORKS__
-// a bit of a hack to adapt code to small m_sig_info VxWorks uses
+// 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
+#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
+#endif
case SI_QUEUE:
report_error( execution_exception::system_error,
"signal: sent by sigqueue()" );
@@ -697,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();
@@ -720,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;
@@ -744,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
@@ -787,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
@@ -903,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 );
@@ -915,6 +921,7 @@ private:
unsigned m_se_id;
void* m_fault_address;
bool m_dir;
+ bool m_timeout;
};
//____________________________________________________________________________//
@@ -929,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 )
{
@@ -1080,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;
}
}
@@ -1139,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;
@@ -1152,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 );
@@ -1209,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 );
}
@@ -1256,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 )
diff --git a/boost/test/impl/framework.ipp b/boost/test/impl/framework.ipp
index 60ba4accfe..c35469eeb3 100644
--- a/boost/test/impl/framework.ipp
+++ b/boost/test/impl/framework.ipp
@@ -34,6 +34,7 @@
#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>
@@ -47,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
@@ -57,6 +58,7 @@
#include <cstdlib>
#include <ctime>
#include <numeric>
+#include <cmath>
#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
#include <iterator>
#endif
@@ -485,7 +487,7 @@ private:
// ************** 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:
@@ -664,7 +666,7 @@ public:
// 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 );
@@ -676,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 ) {
@@ -715,12 +718,13 @@ public:
}
}
- // 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();
@@ -732,12 +736,29 @@ 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, &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 {
@@ -764,17 +785,30 @@ public:
#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 );
@@ -785,9 +819,9 @@ public:
// setup current test case
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();
@@ -816,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;
-
- unsigned elpsed_sec = static_cast<unsigned>(elapsed); // rounding to number of whole seconds
+ if( tu_timeout_microseconds == 0UL || tu_timeout_microseconds == TIMEOUT_EXCEEDED)
+ return tu_timeout_microseconds;
- 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 {
@@ -871,7 +905,7 @@ public:
context_data m_context;
int m_context_idx;
- std::set<test_unit_fixture*> m_global_fixtures;
+ std::set<global_fixture*> m_global_fixtures;
boost::execution_monitor m_aux_em;
@@ -920,6 +954,23 @@ shutdown_loggers_and_reports()
}
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()
{
@@ -1078,7 +1129,7 @@ setup_loggers()
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 {
@@ -1136,7 +1187,7 @@ init( init_unit_test_func init_func, int argc, char* argv[] )
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
@@ -1182,14 +1233,14 @@ finalize_setup_phase( test_unit_id master_tu_id )
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() )
@@ -1225,7 +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
@@ -1350,7 +1407,7 @@ deregister_observer( test_observer& to )
// ************************************************************************** //
void
-register_global_fixture( test_unit_fixture& tuf )
+register_global_fixture( global_fixture& tuf )
{
impl::s_frk_state().m_global_fixtures.insert( &tuf );
}
@@ -1362,7 +1419,7 @@ register_global_fixture( test_unit_fixture& tuf )
// ************************************************************************** //
void
-deregister_global_fixture( test_unit_fixture &tuf )
+deregister_global_fixture( global_fixture &tuf )
{
impl::s_frk_state().m_global_fixtures.erase( &tuf );
}
diff --git a/boost/test/impl/junit_log_formatter.ipp b/boost/test/impl/junit_log_formatter.ipp
index e82e2bd1b0..56b2127b09 100644
--- a/boost/test/impl/junit_log_formatter.ipp
+++ b/boost/test/impl/junit_log_formatter.ipp
@@ -35,6 +35,7 @@
// Boost
#include <boost/version.hpp>
+#include <boost/core/ignore_unused.hpp>
// STL
#include <iostream>
@@ -241,7 +242,10 @@ public:
}
if( tu.p_type == TUT_SUITE ) {
- name += "-setup-teardown";
+ if(tr->p_timed_out)
+ name += "-timed-execution";
+ else
+ name += "-setup-teardown";
}
m_stream << "<testcase assertions" << utils::attr_value() << nb_assertions;
@@ -359,7 +363,7 @@ public:
}
}
else {
- nb_assertions = tr->p_assertions_passed + tr->p_assertions_failed;
+ nb_assertions = static_cast<int>(tr->p_assertions_passed + tr->p_assertions_failed);
}
return nb_assertions;
@@ -417,12 +421,25 @@ public:
if( m_ts.p_id == ts.p_id ) {
m_stream << "<testsuite";
+ // 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
+ << " 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
+ << " 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)
@@ -507,9 +524,9 @@ 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;
}
//____________________________________________________________________________//
@@ -525,10 +542,12 @@ junit_log_formatter::test_unit_start( std::ostream& /*ostr*/, test_unit const& t
//____________________________________________________________________________//
+
void
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();
}
@@ -536,6 +555,7 @@ junit_log_formatter::test_unit_finish( std::ostream& /*ostr*/, test_unit const&
void
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();
}
@@ -543,6 +563,25 @@ junit_log_formatter::test_unit_aborted( std::ostream& /*ostr*/, test_unit const&
//____________________________________________________________________________//
void
+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.
diff --git a/boost/test/impl/plain_report_formatter.ipp b/boost/test/impl/plain_report_formatter.ipp
index cbf5a4c029..c69b895a8f 100644
--- a/boost/test/impl/plain_report_formatter.ipp
+++ b/boost/test/impl/plain_report_formatter.ipp
@@ -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";
diff --git a/boost/test/impl/results_collector.ipp b/boost/test/impl/results_collector.ipp
index cfc34cf793..bda11f2d96 100644
--- a/boost/test/impl/results_collector.ipp
+++ b/boost/test/impl/results_collector.ipp
@@ -17,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>
@@ -56,7 +57,9 @@ test_results::passed() const
p_test_cases_failed == 0 &&
p_assertions_failed <= p_expected_failures &&
// p_test_cases_skipped == 0 &&
- !p_aborted;
+ !p_timed_out &&
+ p_test_cases_timed_out == 0 &&
+ !aborted();
}
//____________________________________________________________________________//
@@ -81,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 );
}
@@ -91,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;
@@ -99,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;
}
@@ -107,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;
@@ -116,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;
}
//____________________________________________________________________________//
@@ -179,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 {
@@ -194,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;
}
@@ -212,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];
@@ -233,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;
@@ -249,6 +266,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 )
{
test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()];
@@ -266,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;
+ }
}
//____________________________________________________________________________//
diff --git a/boost/test/impl/test_tools.ipp b/boost/test/impl/test_tools.ipp
index 2956879326..14934691cb 100644
--- a/boost/test/impl/test_tools.ipp
+++ b/boost/test/impl/test_tools.ipp
@@ -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 {
@@ -374,7 +382,9 @@ report_assertion( assertion_result const& ar,
framework::assertion_result( AR_FAILED );
framework::test_unit_aborted( framework::current_test_unit() );
BOOST_TEST_I_THROW( execution_aborted() );
- return false;
+ // the previous line either throws or aborts and the return below is not reached
+ // return false;
+ BOOST_UNREACHABLE_RETURN(false);
}
return true;
diff --git a/boost/test/impl/test_tree.ipp b/boost/test/impl/test_tree.ipp
index 722b4815b2..d050735ad7 100644
--- a/boost/test/impl/test_tree.ipp
+++ b/boost/test/impl/test_tree.ipp
@@ -30,9 +30,6 @@
#include <boost/test/unit_test_parameters.hpp>
-// Boost
-#include <boost/timer.hpp>
-
// STL
#include <algorithm>
#include <vector>
@@ -532,28 +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()
{
- framework::deregister_global_fixture( *this );
+ this->unregister_from_framework();
}
// ************************************************************************** //
// ************** global_configuration ************** //
// ************************************************************************** //
-global_configuration::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()
{
- framework::deregister_observer( *this );
+ this->unregister_from_framework();
}
//____________________________________________________________________________//
diff --git a/boost/test/impl/unit_test_log.ipp b/boost/test/impl/unit_test_log.ipp
index 40b54be223..c5abfcb304 100644
--- a/boost/test/impl/unit_test_log.ipp
+++ b/boost/test/impl/unit_test_log.ipp
@@ -172,8 +172,9 @@ 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();
@@ -267,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
diff --git a/boost/test/impl/unit_test_main.ipp b/boost/test/impl/unit_test_main.ipp
index cad3d88ec6..c553c45121 100644
--- a/boost/test/impl/unit_test_main.ipp
+++ b/boost/test/impl/unit_test_main.ipp
@@ -37,6 +37,7 @@
#include <stdexcept>
#include <iostream>
#include <iomanip>
+#include <iterator>
#include <set>
#include <boost/test/detail/suppress_warnings.hpp>
diff --git a/boost/test/impl/unit_test_monitor.ipp b/boost/test/impl/unit_test_monitor.ipp
index 70e78513b6..63a04c8f4f 100644
--- a/boost/test/impl/unit_test_monitor.ipp
+++ b/boost/test/impl/unit_test_monitor.ipp
@@ -37,11 +37,11 @@ BOOST_TEST_SINGLETON_CONS_IMPL(unit_test_monitor_t)
// ************************************************************************** //
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 );
diff --git a/boost/test/impl/xml_log_formatter.ipp b/boost/test/impl/xml_log_formatter.ipp
index ef44f1eade..e297d71fda 100644
--- a/boost/test/impl/xml_log_formatter.ipp
+++ b/boost/test/impl/xml_log_formatter.ipp
@@ -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 << '\"'
+ << "/>";
+ }
}
//____________________________________________________________________________//
diff --git a/boost/test/impl/xml_report_formatter.ipp b/boost/test/impl/xml_report_formatter.ipp
index 424ef4ba44..2718895b80 100644
--- a/boost/test/impl/xml_report_formatter.ipp
+++ b/boost/test/impl/xml_report_formatter.ipp
@@ -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 << '>';
diff --git a/boost/test/minimal.hpp b/boost/test/minimal.hpp
index c52295309e..473cc760b7 100644
--- a/boost/test/minimal.hpp
+++ b/boost/test/minimal.hpp
@@ -31,6 +31,9 @@
#ifndef BOOST_TEST_MINIMAL_HPP_071894GER
#define BOOST_TEST_MINIMAL_HPP_071894GER
+#include <boost/config/header_deprecated.hpp>
+BOOST_HEADER_DEPRECATED( "Boost.Test minimal is deprecated. Please convert to the header only variant of Boost.Test." )
+
#define BOOST_CHECK(exp) \
( (exp) \
? static_cast<void>(0) \
diff --git a/boost/test/output/compiler_log_formatter.hpp b/boost/test/output/compiler_log_formatter.hpp
index 50359334b1..5ab0fa43c6 100644
--- a/boost/test/output/compiler_log_formatter.hpp
+++ b/boost/test/output/compiler_log_formatter.hpp
@@ -36,7 +36,7 @@ public:
// Formatter interface
void log_start( std::ostream&, counter_t test_cases_amount );
void log_finish( std::ostream& );
- void log_build_info( std::ostream& );
+ void log_build_info( std::ostream&, bool );
void test_unit_start( std::ostream&, test_unit const& tu );
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed );
diff --git a/boost/test/output/junit_log_formatter.hpp b/boost/test/output/junit_log_formatter.hpp
index 713d3b016c..8ab3b099f2 100644
--- a/boost/test/output/junit_log_formatter.hpp
+++ b/boost/test/output/junit_log_formatter.hpp
@@ -101,12 +101,13 @@ public:
// Formatter interface
void log_start( std::ostream&, counter_t test_cases_amount );
void log_finish( std::ostream& );
- void log_build_info( std::ostream& );
+ void log_build_info( std::ostream&, bool );
void test_unit_start( std::ostream&, test_unit const& tu );
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed );
void test_unit_skipped( std::ostream&, test_unit const& tu, const_string reason );
void test_unit_aborted( std::ostream& os, test_unit const& tu );
+ void test_unit_timed_out( std::ostream& os, test_unit const& tu);
void log_exception_start( std::ostream&, log_checkpoint_data const&, execution_exception const& ex );
void log_exception_finish( std::ostream& );
diff --git a/boost/test/output/xml_log_formatter.hpp b/boost/test/output/xml_log_formatter.hpp
index 1d8dec0f95..c348febc29 100644
--- a/boost/test/output/xml_log_formatter.hpp
+++ b/boost/test/output/xml_log_formatter.hpp
@@ -39,7 +39,7 @@ public:
// Formatter interface
void log_start( std::ostream&, counter_t test_cases_amount );
void log_finish( std::ostream& );
- void log_build_info( std::ostream& );
+ void log_build_info( std::ostream&, bool );
void test_unit_start( std::ostream&, test_unit const& tu );
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed );
diff --git a/boost/test/results_collector.hpp b/boost/test/results_collector.hpp
index 8e8a6202ed..1c26a74a2a 100644
--- a/boost/test/results_collector.hpp
+++ b/boost/test/results_collector.hpp
@@ -62,6 +62,7 @@ public:
(test_results)
(results_collect_helper) ) bool_prop;
+ counter_prop p_test_suites; //!< Number of test suites
counter_prop p_assertions_passed; //!< Number of successful assertions
counter_prop p_assertions_failed; //!< Number of failing assertions
counter_prop p_warnings_failed; //!< Number of warnings
@@ -71,9 +72,12 @@ public:
counter_prop p_test_cases_failed; //!< Number of failing test cases
counter_prop p_test_cases_skipped; //!< Number of skipped test cases
counter_prop p_test_cases_aborted; //!< Number of aborted test cases
+ counter_prop p_test_cases_timed_out; //!< Number of timed out test cases
+ counter_prop p_test_suites_timed_out; //!< Number of timed out test suites
counter_prop p_duration_microseconds; //!< Duration of the test in microseconds
bool_prop p_aborted; //!< Indicates that the test unit execution has been aborted
bool_prop p_skipped; //!< Indicates that the test unit execution has been skipped
+ bool_prop p_timed_out; //!< Indicates that the test unit has timed out
/// Returns true if test unit passed
bool passed() const;
@@ -123,6 +127,7 @@ public:
virtual void test_unit_finish( test_unit const&, unsigned long );
virtual void test_unit_skipped( test_unit const&, const_string );
virtual void test_unit_aborted( test_unit const& );
+ virtual void test_unit_timed_out( test_unit const& );
virtual void assertion_result( unit_test::assertion_result );
virtual void exception_caught( execution_exception const& );
diff --git a/boost/test/tools/context.hpp b/boost/test/tools/context.hpp
index 71650065ef..e5d6625e12 100644
--- a/boost/test/tools/context.hpp
+++ b/boost/test/tools/context.hpp
@@ -17,6 +17,20 @@
// Boost.Test
#include <boost/test/utils/lazy_ostream.hpp>
+#include <boost/test/detail/pp_variadic.hpp>
+
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+#include <boost/preprocessor/variadic/to_seq.hpp>
+#include <boost/preprocessor/variadic/size.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/seq/for_each_i.hpp>
+#include <boost/preprocessor/seq/for_each.hpp>
+#include <boost/preprocessor/seq/enum.hpp>
+#include <boost/preprocessor/control/iif.hpp>
+#include <boost/preprocessor/comparison/equal.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
@@ -47,13 +61,30 @@ private:
::boost::unit_test::framework::add_context( BOOST_TEST_LAZY_MSG( context_descr ) , false ) \
/**/
+#define BOOST_TEST_INFO_SCOPE( context_descr ) \
+ ::boost::test_tools::tt_detail::context_frame BOOST_JOIN( context_frame_, __LINE__ ) = \
+ ::boost::test_tools::tt_detail::context_frame(BOOST_TEST_LAZY_MSG( context_descr ) ) \
+/**/
+
//____________________________________________________________________________//
-#define BOOST_TEST_CONTEXT( context_descr ) \
- if( ::boost::test_tools::tt_detail::context_frame BOOST_JOIN( context_frame_, __LINE__ ) = \
- ::boost::test_tools::tt_detail::context_frame( BOOST_TEST_LAZY_MSG( context_descr ) ) ) \
+
+#define BOOST_CONTEXT_PARAM(r, ctx, i, context_descr) \
+ if( ::boost::test_tools::tt_detail::context_frame BOOST_PP_CAT(ctx, i) = \
+ ::boost::test_tools::tt_detail::context_frame(BOOST_TEST_LAZY_MSG( context_descr ) ) ) \
/**/
+#define BOOST_CONTEXT_PARAMS( params ) \
+ BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONTEXT_PARAM, \
+ BOOST_JOIN( context_frame_, __LINE__ ), \
+ params) \
+/**/
+
+#define BOOST_TEST_CONTEXT( ... ) \
+ BOOST_CONTEXT_PARAMS( BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) ) \
+/**/
+
+
//____________________________________________________________________________//
} // namespace tt_detail
diff --git a/boost/test/tools/detail/print_helper.hpp b/boost/test/tools/detail/print_helper.hpp
index 232fad1509..2400e6e6ac 100644
--- a/boost/test/tools/detail/print_helper.hpp
+++ b/boost/test/tools/detail/print_helper.hpp
@@ -18,7 +18,6 @@
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
-#include <boost/test/detail/workaround.hpp>
// Boost
#include <boost/mpl/or.hpp>
diff --git a/boost/test/tools/fpc_op.hpp b/boost/test/tools/fpc_op.hpp
index c84820bdba..18162e358a 100644
--- a/boost/test/tools/fpc_op.hpp
+++ b/boost/test/tools/fpc_op.hpp
@@ -20,6 +20,7 @@
// Boost
#include <boost/type_traits/common_type.hpp>
+#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
@@ -108,10 +109,10 @@ inline assertion_result
compare_fpv( Lhs const& lhs, Rhs const& rhs, op::EQ<Lhs,Rhs>* )
{
if( lhs == 0 ) {
- return compare_fpv_near_zero( rhs, (op::EQ<Lhs,Rhs>*)0 );
+ return compare_fpv_near_zero<FPT>( rhs, (op::EQ<Lhs,Rhs>*)0 );
}
else if( rhs == 0) {
- return compare_fpv_near_zero( lhs, (op::EQ<Lhs,Rhs>*)0 );
+ return compare_fpv_near_zero<FPT>( lhs, (op::EQ<Lhs,Rhs>*)0 );
}
else {
fpc::close_at_tolerance<FPT> P( fpc_tolerance<FPT>(), fpc::FPC_STRONG );
@@ -131,10 +132,10 @@ inline assertion_result
compare_fpv( Lhs const& lhs, Rhs const& rhs, op::NE<Lhs,Rhs>* )
{
if( lhs == 0 ) {
- return compare_fpv_near_zero( rhs, (op::NE<Lhs,Rhs>*)0 );
+ return compare_fpv_near_zero<FPT>( rhs, (op::NE<Lhs,Rhs>*)0 );
}
else if( rhs == 0 ) {
- return compare_fpv_near_zero( lhs, (op::NE<Lhs,Rhs>*)0 );
+ return compare_fpv_near_zero<FPT>( lhs, (op::NE<Lhs,Rhs>*)0 );
}
else {
fpc::close_at_tolerance<FPT> P( fpc_tolerance<FPT>(), fpc::FPC_WEAK );
@@ -154,7 +155,12 @@ compare_fpv( Lhs const& lhs, Rhs const& rhs, op::NE<Lhs,Rhs>* )
template<typename Lhs,typename Rhs> \
struct name<Lhs,Rhs,typename boost::enable_if_c< \
(fpc::tolerance_based<Lhs>::value && \
- fpc::tolerance_based<Rhs>::value)>::type> { \
+ fpc::tolerance_based<Rhs>::value) || \
+ (fpc::tolerance_based<Lhs>::value && \
+ boost::is_arithmetic<Rhs>::value) || \
+ (boost::is_arithmetic<Lhs>::value && \
+ fpc::tolerance_based<Rhs>::value) \
+ >::type> { \
public: \
typedef typename common_type<Lhs,Rhs>::type FPT; \
typedef name<Lhs,Rhs> OP; \
@@ -211,4 +217,3 @@ BOOST_TEST_FOR_EACH_COMP_OP( DEFINE_FPV_COMPARISON )
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_FPC_OP_HPP_050915GER
-
diff --git a/boost/test/tools/old/impl.hpp b/boost/test/tools/old/impl.hpp
index b975f61b38..0b8f888cbe 100644
--- a/boost/test/tools/old/impl.hpp
+++ b/boost/test/tools/old/impl.hpp
@@ -114,7 +114,7 @@ inline assertion_result equal_impl( char const* left, char* right ) { return equ
inline assertion_result equal_impl( char* left, char* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
#if !defined( BOOST_NO_CWCHAR )
-assertion_result BOOST_TEST_DECL equal_impl( wchar_t const* left, wchar_t const* right );
+BOOST_TEST_DECL assertion_result equal_impl( wchar_t const* left, wchar_t const* right );
inline assertion_result equal_impl( wchar_t* left, wchar_t const* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
inline assertion_result equal_impl( wchar_t const* left, wchar_t* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
inline assertion_result equal_impl( wchar_t* left, wchar_t* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
diff --git a/boost/test/tools/old/interface.hpp b/boost/test/tools/old/interface.hpp
index 2d6f8b78c0..1b23c291a3 100644
--- a/boost/test/tools/old/interface.hpp
+++ b/boost/test/tools/old/interface.hpp
@@ -20,6 +20,8 @@
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/seq/to_tuple.hpp>
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
@@ -95,7 +97,7 @@ do {
//____________________________________________________________________________//
-#define BOOST_CHECK_THROW_IMPL( S, E, P, postfix, TL ) \
+#define BOOST_CHECK_THROW_IMPL( S, E, P, postfix, TL ) \
do { \
try { \
BOOST_TEST_PASSPOINT(); \
@@ -103,9 +105,9 @@ do {
BOOST_TEST_TOOL_IMPL( 2, false, "exception " BOOST_STRINGIZE(E) " expected but not raised", \
TL, CHECK_MSG, _ ); \
} catch( E const& ex ) { \
- ::boost::unit_test::ut_detail::ignore_unused_variable_warning( ex ); \
- BOOST_TEST_TOOL_IMPL( 2, P, \
- "exception \"" BOOST_STRINGIZE( E )"\" raised as expected" postfix, \
+ boost::ignore_unused( ex ); \
+ BOOST_TEST_TOOL_IMPL( 2, P, \
+ "exception \"" BOOST_STRINGIZE( E )"\" raised as expected" postfix, \
TL, CHECK_MSG, _ ); \
} \
} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
diff --git a/boost/test/tree/decorator.hpp b/boost/test/tree/decorator.hpp
index 6537152538..c9be22f6d0 100644
--- a/boost/test/tree/decorator.hpp
+++ b/boost/test/tree/decorator.hpp
@@ -59,14 +59,19 @@ public:
void reset();
+ void stack();
+
std::vector<base_ptr> get_lazy_decorators() const;
- // singleton pattern
- BOOST_TEST_SINGLETON_CONS( collector_t )
+ // singleton pattern without ctor
+ BOOST_TEST_SINGLETON_CONS_NO_CTOR( collector_t )
+
+private:
+ // Class invariant: minimal size is 1.
+ collector_t() : m_tu_decorators_stack(1) {}
- private:
// Data members
- std::vector<base_ptr> m_tu_decorators;
+ std::vector< std::vector<base_ptr> > m_tu_decorators_stack;
};
@@ -77,7 +82,7 @@ public:
class BOOST_TEST_DECL base {
public:
// composition interface
- collector_t& operator*() const;
+ virtual collector_t& operator*() const;
// application interface
virtual void apply( test_unit& tu ) = 0;
@@ -90,6 +95,30 @@ protected:
};
// ************************************************************************** //
+// ************** decorator::stack_decorator ************** //
+// ************************************************************************** //
+
+//!@ A decorator that creates a new stack in the collector
+//!
+//! This decorator may be used in places where the currently accumulated decorators
+//! in the collector should be applied to lower levels of the hierarchy rather
+//! than the current one. This is for instance for dataset test cases, where the
+//! macro does not let the user specify decorators for the underlying generated tests
+//! (but rather on the main generator function), applying the stack_decorator at the
+//! parent level lets us consume the decorator at the underlying test cases level.
+class BOOST_TEST_DECL stack_decorator : public decorator::base {
+public:
+ explicit stack_decorator() {}
+
+ virtual collector_t& operator*() const;
+
+private:
+ // decorator::base interface
+ virtual void apply( test_unit& tu );
+ virtual base_ptr clone() const { return base_ptr(new stack_decorator()); }
+};
+
+// ************************************************************************** //
// ************** decorator::label ************** //
// ************************************************************************** //
diff --git a/boost/test/tree/global_fixture.hpp b/boost/test/tree/global_fixture.hpp
index 7c96d34e89..f64ddeae2d 100644
--- a/boost/test/tree/global_fixture.hpp
+++ b/boost/test/tree/global_fixture.hpp
@@ -37,11 +37,19 @@ public:
// Constructor
global_configuration();
+ /// Unregisters the global fixture from the framework
+ ///
+ /// This is called by the framework at shutdown time
+ void unregister_from_framework();
+
// Dtor
virtual ~global_configuration();
// Happens after the framework global observer init has been done
virtual int priority() { return 1; }
+
+private:
+ bool registered;
};
@@ -56,8 +64,16 @@ public:
// Constructor
global_fixture();
+ /// Unregisters the global fixture from the framework
+ ///
+ /// This is called by the framework at shutdown time
+ void unregister_from_framework();
+
// Dtor
virtual ~global_fixture();
+
+private:
+ bool registered;
};
//____________________________________________________________________________//
diff --git a/boost/test/tree/observer.hpp b/boost/test/tree/observer.hpp
index bd6fc9bff5..46b26905e3 100644
--- a/boost/test/tree/observer.hpp
+++ b/boost/test/tree/observer.hpp
@@ -72,6 +72,12 @@ public:
virtual void test_unit_skipped( test_unit const& tu, const_string ) { test_unit_skipped( tu ); }
virtual void test_unit_skipped( test_unit const& ) {} ///< backward compatibility
+ //! Called when the test timed out
+ //!
+ //! This function is called to signal that a test unit (case or suite) timed out.
+ //! A valid test unit is available through boost::unit_test::framework::current_test_unit
+ virtual void test_unit_timed_out( test_unit const& ) {}
+
//! Called when a test unit indicates a fatal error.
//!
//! A fatal error happens when
@@ -79,14 +85,8 @@ public:
//! - an unexpected exception is caught by the Boost.Test framework
virtual void test_unit_aborted( test_unit const& ) {}
- virtual void assertion_result( unit_test::assertion_result ar )
+ virtual void assertion_result( unit_test::assertion_result /* ar */ )
{
- switch( ar ) {
- case AR_PASSED: assertion_result( true ); break;
- case AR_FAILED: assertion_result( false ); break;
- case AR_TRIGGERED: break;
- default: break;
- }
}
//! Called when an exception is intercepted
@@ -101,8 +101,6 @@ public:
virtual int priority() { return 0; }
protected:
- //! Deprecated
- virtual void assertion_result( bool /* passed */ ) {}
BOOST_TEST_PROTECTED_VIRTUAL ~test_observer() {}
};
diff --git a/boost/test/tree/test_case_template.hpp b/boost/test/tree/test_case_template.hpp
index e862980220..6aa0bb7e3b 100644
--- a/boost/test/tree/test_case_template.hpp
+++ b/boost/test/tree/test_case_template.hpp
@@ -16,7 +16,6 @@
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
-#include <boost/test/detail/workaround.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/utils/class_properties.hpp>
@@ -30,6 +29,10 @@
#include <boost/mpl/identity.hpp>
#include <boost/type.hpp>
#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#include <boost/type_traits/is_lvalue_reference.hpp>
+#include <boost/type_traits/is_rvalue_reference.hpp>
+#include <boost/type_traits/remove_reference.hpp>
#include <boost/function/function0.hpp>
#if defined(BOOST_NO_TYPEID) || defined(BOOST_NO_RTTI)
@@ -43,9 +46,9 @@
#include <list> // for std::list
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
- !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
!defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
- #include <tuple>
+ #include <type_traits>
+ #include <boost/mpl/is_sequence.hpp>
#endif
#include <boost/test/detail/suppress_warnings.hpp>
@@ -91,8 +94,16 @@ struct generate_test_case_4_type {
#else
full_name += BOOST_CURRENT_FUNCTION;
#endif
- if( boost::is_const<TestType>::value )
+ typedef typename boost::remove_reference<TestType>::type TestTypewoRef;
+ if( boost::is_const<TestTypewoRef>::value )
full_name += "_const";
+ if( boost::is_volatile<TestTypewoRef>::value )
+ full_name += "_volatile";
+ if( boost::is_rvalue_reference<TestType>::value )
+ full_name += "_refref";
+ else if( boost::is_lvalue_reference<TestType>::value )
+ full_name += "_ref";
+
full_name += '>';
m_holder.m_test_cases.push_back( new test_case( ut_detail::normalize_test_case_name( full_name ),
@@ -130,7 +141,7 @@ public:
mutable std::list<test_unit*> m_test_cases;
};
-template<typename TestCaseTemplate,typename TestTypesList>
+template<typename TestCaseTemplate,typename TestTypesList, typename enabler = void>
class template_test_case_gen : public template_test_case_gen_base {
public:
// Constructor
@@ -144,26 +155,22 @@ public:
// Describing template test cases with tuples
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
- !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
!defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && \
!defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
-template<typename TestCaseTemplate, typename... tuple_parameter_pack>
-class template_test_case_gen<TestCaseTemplate, std::tuple<tuple_parameter_pack...> > : public template_test_case_gen_base {
-
- template<int... Is>
- struct seq { };
-
- template<int N, int... Is>
- struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };
-
- template<int... Is>
- struct gen_seq<0, Is...> : seq<Is...> { };
-
- template<typename tuple_t, typename F, int... Is>
- void for_each(F &f, seq<Is...>)
+template<typename TestCaseTemplate,
+ template <class ...> class C,
+ typename... parameter_pack>
+class template_test_case_gen<
+ TestCaseTemplate,
+ C<parameter_pack...>,
+ typename std::enable_if<!boost::mpl::is_sequence<C<parameter_pack...>>::value>::type >
+ : public template_test_case_gen_base {
+
+ template<typename F>
+ void for_each(F &f)
{
- auto l = { (f(mpl::identity<typename std::tuple_element<Is, tuple_t>::type>()), 0)... };
+ auto l = { (f(mpl::identity<parameter_pack>()), 0)... };
(void)l; // silence warning
}
@@ -171,17 +178,19 @@ public:
// Constructor
template_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line )
{
- using tuple_t = std::tuple<tuple_parameter_pack...>;
- using this_type = template_test_case_gen<TestCaseTemplate, tuple_t >;
+ using this_type = template_test_case_gen<
+ TestCaseTemplate,
+ C<parameter_pack...>,
+ typename std::enable_if<!boost::mpl::is_sequence<C<parameter_pack...>>::value>::type>;
using single_test_gen = generate_test_case_4_type<this_type, TestCaseTemplate>;
single_test_gen op( tc_name, tc_file, tc_line, *this );
- this->for_each<tuple_t>(op, gen_seq<sizeof...(tuple_parameter_pack)>());
+ this->for_each(op);
}
};
-#endif /* C++11 variadic, tuples and type alias */
+#endif /* C++11 variadic, type alias */
} // namespace ut_detail
} // unit_test
diff --git a/boost/test/tree/test_unit.hpp b/boost/test/tree/test_unit.hpp
index 48033af897..45956f689d 100644
--- a/boost/test/tree/test_unit.hpp
+++ b/boost/test/tree/test_unit.hpp
@@ -20,6 +20,7 @@
#include <boost/test/tree/decorator.hpp>
#include <boost/test/tree/fixture.hpp>
+#include <boost/test/framework.hpp>
#include <boost/test/tools/assertion_result.hpp>
@@ -42,8 +43,7 @@ namespace boost {
namespace unit_test {
namespace framework {
-class state;
-BOOST_TEST_DECL master_test_suite_t& master_test_suite();
+ class state;
}
// ************************************************************************** //
@@ -229,7 +229,7 @@ public:
int argc;
char** argv;
- friend master_test_suite_t& boost::unit_test::framework::master_test_suite();
+ friend BOOST_TEST_DECL master_test_suite_t& boost::unit_test::framework::master_test_suite();
};
// ************************************************************************** //
diff --git a/boost/test/unit_test_log.hpp b/boost/test/unit_test_log.hpp
index d65a728747..5de9f43340 100644
--- a/boost/test/unit_test_log.hpp
+++ b/boost/test/unit_test_log.hpp
@@ -119,6 +119,7 @@ public:
virtual void test_unit_finish( test_unit const&, unsigned long elapsed );
virtual void test_unit_skipped( test_unit const&, const_string );
virtual void test_unit_aborted( test_unit const& );
+ virtual void test_unit_timed_out( test_unit const& );
virtual void exception_caught( execution_exception const& ex );
diff --git a/boost/test/unit_test_log_formatter.hpp b/boost/test/unit_test_log_formatter.hpp
index 79b74e0849..e4648b4dab 100644
--- a/boost/test/unit_test_log_formatter.hpp
+++ b/boost/test/unit_test_log_formatter.hpp
@@ -139,8 +139,9 @@ public:
/// Invoked when Unit Test Framework build information is requested
///
- /// @param[in] os output stream to write a messages into
- virtual void log_build_info( std::ostream& os ) = 0;
+ /// @param[in] os output stream to write a messages into
+ /// @param[in] log_build_info indicates if build info should be logged or not
+ virtual void log_build_info( std::ostream& os, bool log_build_info = true ) = 0;
// @}
// @name Test unit start/finish
@@ -176,6 +177,10 @@ public:
/// Invoked when a test unit is aborted
virtual void test_unit_aborted( std::ostream& /* os */, test_unit const& /* tu */) {}
+ /// Invoked when a test unit times-out
+ virtual void test_unit_timed_out( std::ostream& /* os */, test_unit const& /* tu */) {}
+
+
// @}
// @name Uncaught exception report
diff --git a/boost/test/unit_test_monitor.hpp b/boost/test/unit_test_monitor.hpp
index b056051caf..3e7919a5aa 100644
--- a/boost/test/unit_test_monitor.hpp
+++ b/boost/test/unit_test_monitor.hpp
@@ -45,7 +45,8 @@ public:
static bool is_critical_error( error_level e ) { return e <= fatal_error; }
// monitor method
- error_level execute_and_translate( boost::function<void ()> const& func, unsigned timeout = 0 );
+ // timeout is expressed in seconds
+ error_level execute_and_translate( boost::function<void ()> const& func, unsigned long int timeout_microseconds = 0 );
// singleton pattern
BOOST_TEST_SINGLETON_CONS( unit_test_monitor_t )
diff --git a/boost/test/unit_test_suite.hpp b/boost/test/unit_test_suite.hpp
index 698362e588..f55eff7291 100644
--- a/boost/test/unit_test_suite.hpp
+++ b/boost/test/unit_test_suite.hpp
@@ -235,12 +235,15 @@ struct BOOST_AUTO_TC_INVOKER( test_name ) { \
template<typename TestType> \
static void run( boost::type<TestType>* = 0 ) \
{ \
- BOOST_TEST_CHECKPOINT('"' << #test_name <<"\" fixture entry."); \
- test_name<TestType> t; boost::unit_test::setup_conditional(t); \
- BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry."); \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture ctor"); \
+ test_name<TestType> t; \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture setup"); \
+ boost::unit_test::setup_conditional(t); \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" test entry"); \
t.test_method(); \
- BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit."); \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture teardown");\
boost::unit_test::teardown_conditional(t); \
+ BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture dtor"); \
} \
}; \
\
@@ -322,7 +325,7 @@ static boost::unit_test::ut_detail::global_fixture_impl<F> BOOST_JOIN( gf_, F )
#define BOOST_TEST_DECORATOR( D ) \
static boost::unit_test::decorator::collector_t const& \
-BOOST_TEST_APPEND_UNIQUE_ID(decorator_collector) = D; \
+BOOST_TEST_APPEND_UNIQUE_ID(decorator_collector) BOOST_ATTRIBUTE_UNUSED = D; \
/**/
// ************************************************************************** //
@@ -362,7 +365,7 @@ typedef ::boost::unit_test::ut_detail::nil_t BOOST_AUTO_TEST_CASE_FIXTURE;
#define BOOST_AUTO_TU_REGISTRAR( test_name ) \
static boost::unit_test::ut_detail::auto_test_unit_registrar \
-BOOST_TEST_APPEND_UNIQUE_ID( BOOST_JOIN( test_name, _registrar ) ) \
+BOOST_TEST_APPEND_UNIQUE_ID( BOOST_JOIN( test_name, _registrar ) ) BOOST_ATTRIBUTE_UNUSED \
/**/
#define BOOST_AUTO_TC_INVOKER( test_name ) BOOST_JOIN( test_name, _invoker )
#define BOOST_AUTO_TC_UNIQUE_ID( test_name ) BOOST_JOIN( test_name, _id )
diff --git a/boost/test/utils/basic_cstring/basic_cstring.hpp b/boost/test/utils/basic_cstring/basic_cstring.hpp
index cec0214b73..3f33e82649 100644
--- a/boost/test/utils/basic_cstring/basic_cstring.hpp
+++ b/boost/test/utils/basic_cstring/basic_cstring.hpp
@@ -39,7 +39,7 @@ namespace unit_test {
// ************************************************************************** //
template<typename CharT>
-class basic_cstring {
+class BOOST_SYMBOL_VISIBLE basic_cstring {
typedef basic_cstring<CharT> self_type;
public:
// Subtypes
@@ -163,15 +163,20 @@ private:
// Data members
iterator m_begin;
iterator m_end;
+ static CharT null;
};
//____________________________________________________________________________//
template<typename CharT>
+CharT basic_cstring<CharT>::null = 0;
+
+//____________________________________________________________________________//
+
+template<typename CharT>
inline typename basic_cstring<CharT>::pointer
basic_cstring<CharT>::null_str()
{
- static CharT null = 0;
return &null;
}
diff --git a/boost/test/utils/basic_cstring/basic_cstring_fwd.hpp b/boost/test/utils/basic_cstring/basic_cstring_fwd.hpp
index f0622263d1..88c3406896 100644
--- a/boost/test/utils/basic_cstring/basic_cstring_fwd.hpp
+++ b/boost/test/utils/basic_cstring/basic_cstring_fwd.hpp
@@ -16,13 +16,13 @@
#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
-#include <boost/detail/workaround.hpp>
+#include <boost/test/detail/config.hpp>
namespace boost {
namespace unit_test {
-template<typename CharT> class basic_cstring;
+template<typename CharT> class BOOST_SYMBOL_VISIBLE basic_cstring;
typedef basic_cstring<char const> const_string;
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590041))
typedef const_string literal_string;
@@ -37,4 +37,3 @@ typedef char const* const c_literal_string;
} // namespace boost
#endif // BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
-
diff --git a/boost/test/utils/foreach.hpp b/boost/test/utils/foreach.hpp
index 68462ae719..ea1adc58cc 100644
--- a/boost/test/utils/foreach.hpp
+++ b/boost/test/utils/foreach.hpp
@@ -26,7 +26,6 @@
// Boost
#include <boost/type.hpp>
#include <boost/mpl/bool.hpp>
-#include <boost/test/detail/workaround.hpp>
#include <boost/type_traits/is_const.hpp>
diff --git a/boost/test/utils/lazy_ostream.hpp b/boost/test/utils/lazy_ostream.hpp
index 26bd8ed385..37ad668d92 100644
--- a/boost/test/utils/lazy_ostream.hpp
+++ b/boost/test/utils/lazy_ostream.hpp
@@ -28,11 +28,11 @@
namespace boost {
namespace unit_test {
-class lazy_ostream {
+class BOOST_TEST_DECL lazy_ostream {
public:
virtual ~lazy_ostream() {}
- static lazy_ostream& instance() { static lazy_ostream inst; return inst; }
+ static lazy_ostream& instance() { return inst; }
friend std::ostream& operator<<( std::ostream& ostr, lazy_ostream const& o ) { return o( ostr ); }
@@ -47,6 +47,7 @@ protected:
private:
// Data members
bool m_empty;
+ static lazy_ostream inst;
};
//____________________________________________________________________________//
diff --git a/boost/test/utils/rtti.hpp b/boost/test/utils/rtti.hpp
index b230692d80..84225b0921 100644
--- a/boost/test/utils/rtti.hpp
+++ b/boost/test/utils/rtti.hpp
@@ -17,6 +17,7 @@
// C Runtime
#include <cstddef>
+#include <boost/test/detail/config.hpp>
namespace boost {
namespace rtti {
@@ -30,7 +31,7 @@ typedef std::ptrdiff_t id_t;
namespace rtti_detail {
template<typename T>
-struct rttid_holder {
+struct BOOST_TEST_DECL rttid_holder {
static id_t id() { return reinterpret_cast<id_t>( &inst() ); }
private:
@@ -44,7 +45,7 @@ private:
//____________________________________________________________________________//
template<typename T>
-inline id_t
+BOOST_TEST_DECL inline id_t
type_id()
{
return rtti_detail::rttid_holder<T>::id();
diff --git a/boost/test/utils/runtime/cla/parser.hpp b/boost/test/utils/runtime/cla/parser.hpp
index bd3df7090c..9e8601f517 100644
--- a/boost/test/utils/runtime/cla/parser.hpp
+++ b/boost/test/utils/runtime/cla/parser.hpp
@@ -109,12 +109,12 @@ struct parameter_trie {
// ************** runtime::cla::report_foreing_token ************** //
// ************************************************************************** //
-static void
+static void
report_foreing_token( cstring program_name, cstring token )
{
std::cerr << "Boost.Test WARNING: token \"" << token << "\" does not correspond to the Boost.Test argument \n"
<< " and should be placed after all Boost.Test arguments and the -- separator.\n"
- << " For example: " << program_name << " --random -- " << token << "\n";
+ << " For example: " << program_name << " --random -- " << token << "\n";
}
} // namespace rt_cla_detail
@@ -203,7 +203,7 @@ public:
if( negative_form ) {
BOOST_TEST_I_ASSRT( found_id.m_negatable,
- format_error( found_param->p_name )
+ format_error( found_param->p_name )
<< "Parameter tag " << found_id.m_tag << " is not negatable." );
curr_token.trim_left( m_negation_prefix.size() );
@@ -213,16 +213,16 @@ public:
bool should_go_to_next = true;
cstring value;
-
+
// Skip validations if parameter has optional value and we are at the end of token
if( !value_separator.is_empty() || !found_param->p_has_optional_value ) {
-
+
// we are given a separator or there is no optional value
-
+
// Validate and skip value separator in the input
BOOST_TEST_I_ASSRT( found_id.m_value_separator == value_separator,
- format_error( found_param->p_name )
+ format_error( found_param->p_name )
<< "Invalid separator for the parameter "
<< found_param->p_name
<< " in the argument " << tr.current_token() );
@@ -247,7 +247,7 @@ public:
value = curr_token;
if( value.is_empty() ) {
tr.next_token(); // tokenization broke the value, we check the next one
-
+
if(!found_param->p_has_optional_value) {
// there is no separator and there is no optional value
// we look for the value on the next token
@@ -261,7 +261,7 @@ public:
// example "-c" (defaults to true)
// and commit this as the value if this is not a token
cstring value_check = tr.current_token();
-
+
cstring prefix_test, name_test, value_separator_test;
bool negative_form_test;
if( validate_token_format( value_check, prefix_test, name_test, value_separator_test, negative_form_test )
@@ -328,7 +328,7 @@ public:
}
void
- usage(std::ostream& ostr,
+ usage(std::ostream& ostr,
cstring param_name = cstring(),
bool use_color = true)
{
@@ -340,13 +340,13 @@ public:
param->usage( ostr, m_negation_prefix );
}
else {
- ostr << "\n The program '" << m_program_name << "' is a Boost.test module containing unit tests.";
-
+ ostr << "\n The program '" << m_program_name << "' is a Boost.Test module containing unit tests.";
+
{
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::ORIGINAL );
ostr << "\n\n Usage\n ";
}
-
+
{
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
ostr << m_program_name << " [Boost.Test argument]... ";
@@ -359,7 +359,7 @@ public:
ostr << "\n\n Use\n ";
{
-
+
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
ostr << m_program_name << " --help";
}
@@ -372,8 +372,8 @@ public:
}
void
- help(std::ostream& ostr,
- parameters_store const& parameters,
+ help(std::ostream& ostr,
+ parameters_store const& parameters,
cstring param_name,
bool use_color = true)
{
@@ -431,10 +431,10 @@ public:
ostr << "\n\n The following parameters are supported:\n";
- BOOST_TEST_FOREACH(
- parameters_store::storage_type::value_type const&,
- v,
- parameters.all() )
+ BOOST_TEST_FOREACH(
+ parameters_store::storage_type::value_type const&,
+ v,
+ parameters.all() )
{
basic_param_ptr param = v.second;
ostr << "\n";
diff --git a/boost/test/utils/runtime/errors.hpp b/boost/test/utils/runtime/errors.hpp
index 056a823e33..30c0389f7d 100644
--- a/boost/test/utils/runtime/errors.hpp
+++ b/boost/test/utils/runtime/errors.hpp
@@ -61,7 +61,7 @@ protected:
~init_error() BOOST_NOEXCEPT_OR_NOTHROW {}
};
-class input_error : public param_error {
+class BOOST_SYMBOL_VISIBLE input_error : public param_error {
protected:
explicit input_error( cstring param_name ) : param_error( param_name ) {}
~input_error() BOOST_NOEXCEPT_OR_NOTHROW {}
@@ -133,7 +133,7 @@ public:
// ************************************************************************** //
#define SPECIFIC_EX_TYPE( type, base ) \
-class type : public specific_param_error<type,base> { \
+class BOOST_SYMBOL_VISIBLE type : public specific_param_error<type,base> { \
public: \
explicit type( cstring param_name = cstring() ) \
: specific_param_error<type,base>( param_name ) \
@@ -171,7 +171,7 @@ public:
std::vector<cstring> m_amb_candidates;
};
-class unrecognized_param : public specific_param_error<unrecognized_param, input_error> {
+class BOOST_SYMBOL_VISIBLE unrecognized_param : public specific_param_error<unrecognized_param, input_error> {
public:
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
explicit unrecognized_param( std::vector<cstring>&& type_candidates )
diff --git a/boost/test/utils/setcolor.hpp b/boost/test/utils/setcolor.hpp
index 915c9962a3..ce3e9eee02 100644
--- a/boost/test/utils/setcolor.hpp
+++ b/boost/test/utils/setcolor.hpp
@@ -18,6 +18,8 @@
// Boost.Test
#include <boost/test/detail/config.hpp>
+#include <boost/core/ignore_unused.hpp>
+
// STL
#include <iostream>
#include <cstdio>
@@ -83,7 +85,11 @@ public:
term_color::_ bg = term_color::ORIGINAL )
: m_is_color_output(is_color_output)
{
- m_command_size = std::sprintf( m_control_command, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40 );
+ m_command_size = std::sprintf( m_control_command, "%c[%c;3%c;4%cm",
+ 0x1B,
+ static_cast<char>(attr + '0'),
+ static_cast<char>(fg + '0'),
+ static_cast<char>(bg + '0'));
}
friend std::ostream&
@@ -306,7 +312,7 @@ private:
#define BOOST_TEST_SCOPE_SETCOLOR( is_color_output, os, attr, color ) \
utils::scope_setcolor const sc(is_color_output, os, utils::attr, utils::color); \
- ut_detail::ignore_unused_variable_warning( sc ) \
+ boost::ignore_unused( sc ) \
/**/
} // namespace utils
diff --git a/boost/test/utils/timer.hpp b/boost/test/utils/timer.hpp
new file mode 100644
index 0000000000..035fb4fd13
--- /dev/null
+++ b/boost/test/utils/timer.hpp
@@ -0,0 +1,164 @@
+// (C) Copyright Raffi Enficiaud 2019.
+// 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.
+//
+// Description : timer and elapsed types
+// ***************************************************************************
+
+#ifndef BOOST_TEST_UTILS_TIMER_HPP
+#define BOOST_TEST_UTILS_TIMER_HPP
+
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+#include <utility>
+#include <ctime>
+
+# if defined(_WIN32) || defined(__CYGWIN__)
+# define BOOST_TEST_TIMER_WINDOWS_API
+# elif defined(__MACH__)// && !defined(CLOCK_MONOTONIC)
+# // we compile for all macs the same, CLOCK_MONOTONIC introduced in 10.12
+# define BOOST_TEST_TIMER_MACH_API
+# else
+# define BOOST_TEST_TIMER_POSIX_API
+# if !defined(CLOCK_MONOTONIC)
+# error "CLOCK_MONOTONIC not defined"
+# endif
+# endif
+
+# if defined(BOOST_TEST_TIMER_WINDOWS_API)
+# include <windows.h>
+# elif defined(BOOST_TEST_TIMER_MACH_API)
+# include <mach/mach_time.h>
+//# include <mach/mach.h> /* host_get_clock_service, mach_... */
+# else
+# include <sys/time.h>
+# endif
+
+# ifdef BOOST_NO_STDC_NAMESPACE
+ namespace std { using ::clock_t; using ::clock; }
+# endif
+
+namespace boost {
+namespace unit_test {
+namespace timer {
+
+ struct elapsed_time
+ {
+ typedef boost::int_least64_t nanosecond_type;
+
+ nanosecond_type wall;
+ nanosecond_type system;
+ void clear() {
+ wall = 0;
+ system = 0;
+ }
+ };
+
+ inline double
+ microsecond_wall_time( elapsed_time const& elapsed )
+ {
+ return elapsed.wall / 1E3;
+ }
+
+ inline double
+ second_wall_time( elapsed_time const& elapsed )
+ {
+ return elapsed.wall / 1E9;
+ }
+
+ namespace details {
+ #if defined(BOOST_TEST_TIMER_WINDOWS_API)
+ elapsed_time::nanosecond_type get_tick_freq() {
+ LARGE_INTEGER freq;
+ ::QueryPerformanceFrequency( &freq );
+ return static_cast<elapsed_time::nanosecond_type>(freq.QuadPart);
+ }
+ #elif defined(BOOST_TEST_TIMER_MACH_API)
+ std::pair<elapsed_time::nanosecond_type, elapsed_time::nanosecond_type> get_time_base() {
+ mach_timebase_info_data_t timebase;
+ if(mach_timebase_info(&timebase) == 0)
+ return std::pair<elapsed_time::nanosecond_type, elapsed_time::nanosecond_type>(timebase.numer, timebase.denom);
+ return std::pair<elapsed_time::nanosecond_type, elapsed_time::nanosecond_type>(0, 1);
+ }
+ #endif
+ }
+
+ //! Simple timing class
+ //!
+ //! This class measures the wall clock time.
+ class timer
+ {
+ public:
+ timer()
+ {
+ restart();
+ }
+ void restart()
+ {
+ _start_time_clock = std::clock();
+ #if defined(BOOST_TEST_TIMER_WINDOWS_API)
+ ::QueryPerformanceCounter(&_start_time_wall);
+ #elif defined(BOOST_TEST_TIMER_MACH_API)
+ _start_time_wall = mach_absolute_time();
+ #else
+ if( ::clock_gettime( CLOCK_MONOTONIC, &_start_time_wall ) != 0 )
+ {
+ _start_time_wall.tv_nsec = -1;
+ _start_time_wall.tv_sec = -1;
+ }
+ #endif
+ }
+
+ // return elapsed time in seconds
+ elapsed_time elapsed() const
+ {
+ typedef elapsed_time::nanosecond_type nanosecond_type;
+ static const double clock_to_nano_seconds = 1E9 / CLOCKS_PER_SEC;
+ elapsed_time return_value;
+
+ // processor / system time
+ return_value.system = static_cast<nanosecond_type>(double(std::clock() - _start_time_clock) * clock_to_nano_seconds);
+
+#if defined(BOOST_TEST_TIMER_WINDOWS_API)
+ static const nanosecond_type tick_per_sec = details::get_tick_freq();
+ LARGE_INTEGER end_time;
+ ::QueryPerformanceCounter(&end_time);
+ return_value.wall = static_cast<nanosecond_type>(((end_time.QuadPart - _start_time_wall.QuadPart) * 1E9) / tick_per_sec);
+#elif defined(BOOST_TEST_TIMER_MACH_API)
+ static std::pair<nanosecond_type, nanosecond_type> timebase = details::get_time_base();
+ nanosecond_type clock = mach_absolute_time() - _start_time_wall;
+ return_value.wall = static_cast<nanosecond_type>((clock * timebase.first) / timebase.second);
+#else
+ struct timespec end_time;
+ if( ::clock_gettime( CLOCK_MONOTONIC, &end_time ) == 0 )
+ {
+ return_value.wall = static_cast<nanosecond_type>((end_time.tv_sec - _start_time_wall.tv_sec) * 1E9 + (end_time.tv_nsec - _start_time_wall.tv_nsec));
+ }
+#endif
+
+ return return_value;
+ }
+
+ private:
+ std::clock_t _start_time_clock;
+ #if defined(BOOST_TEST_TIMER_WINDOWS_API)
+ LARGE_INTEGER _start_time_wall;
+ #elif defined(BOOST_TEST_TIMER_MACH_API)
+ elapsed_time::nanosecond_type _start_time_wall;
+ #else
+ struct timespec _start_time_wall;
+ #endif
+ };
+
+
+//____________________________________________________________________________//
+
+} // namespace timer
+} // namespace unit_test
+} // namespace boost
+
+#endif // BOOST_TEST_UTILS_TIMER_HPP
+