unit_test_log.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // (C) Copyright Gennadiy Rozental 2001.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // See http://www.boost.org/libs/test for the library home page.
  6. //
  7. /// @file
  8. /// @brief defines singleton class unit_test_log and all manipulators.
  9. /// unit_test_log has output stream like interface. It's implementation is
  10. /// completely hidden with pimple idiom
  11. // ***************************************************************************
  12. #ifndef BOOST_TEST_UNIT_TEST_LOG_HPP_071894GER
  13. #define BOOST_TEST_UNIT_TEST_LOG_HPP_071894GER
  14. // Boost.Test
  15. #include <boost/test/tree/observer.hpp>
  16. #include <boost/test/detail/global_typedef.hpp>
  17. #include <boost/test/detail/log_level.hpp>
  18. #include <boost/test/detail/fwd_decl.hpp>
  19. #include <boost/test/utils/wrap_stringstream.hpp>
  20. #include <boost/test/utils/lazy_ostream.hpp>
  21. // Boost
  22. // STL
  23. #include <iosfwd> // for std::ostream&
  24. #include <boost/test/detail/suppress_warnings.hpp>
  25. //____________________________________________________________________________//
  26. namespace boost {
  27. namespace unit_test {
  28. // ************************************************************************** //
  29. // ************** log manipulators ************** //
  30. // ************************************************************************** //
  31. namespace log {
  32. struct BOOST_TEST_DECL begin {
  33. begin( const_string fn, std::size_t ln )
  34. : m_file_name( fn )
  35. , m_line_num( ln )
  36. {}
  37. const_string m_file_name;
  38. std::size_t m_line_num;
  39. };
  40. struct end {};
  41. } // namespace log
  42. // ************************************************************************** //
  43. // ************** entry_value_collector ************** //
  44. // ************************************************************************** //
  45. namespace ut_detail {
  46. class BOOST_TEST_DECL entry_value_collector {
  47. public:
  48. // Constructors
  49. entry_value_collector() : m_last( true ) {}
  50. entry_value_collector( entry_value_collector const& rhs ) : m_last( true ) { rhs.m_last = false; }
  51. ~entry_value_collector();
  52. // collection interface
  53. entry_value_collector const& operator<<( lazy_ostream const& ) const;
  54. entry_value_collector const& operator<<( const_string ) const;
  55. private:
  56. // Data members
  57. mutable bool m_last;
  58. };
  59. } // namespace ut_detail
  60. // ************************************************************************** //
  61. // ************** unit_test_log ************** //
  62. // ************************************************************************** //
  63. /// @brief Manages the sets of loggers, their streams and log levels
  64. ///
  65. /// The Boost.Test framework allows for having several formatters/loggers at the same time, each of which
  66. /// having their own log level and output stream.
  67. ///
  68. /// This class serves the purpose of
  69. /// - exposing an interface to the test framework (as a boost::unit_test::test_observer)
  70. /// - exposing an interface to the testing tools
  71. /// - managing several loggers
  72. ///
  73. /// @note Accesses to the functions exposed by this class are made through the singleton
  74. /// @c boost::unit_test::unit_test_log.
  75. ///
  76. /// Users/developers willing to implement their own formatter need to:
  77. /// - implement a boost::unit_test::unit_test_log_formatter that will output the desired format
  78. /// - register the formatter during a eg. global fixture using the method @c set_formatter (though the framework singleton).
  79. ///
  80. /// @warning this observer has a higher priority than the @ref boost::unit_test::results_collector_t. This means
  81. /// that the various @ref boost::unit_test::test_results associated to each test unit may not be available at the time
  82. /// the @c test_unit_start, @c test_unit_finish ... are called.
  83. ///
  84. /// @see
  85. /// - boost::unit_test::test_observer
  86. /// - boost::unit_test::unit_test_log_formatter
  87. class BOOST_TEST_DECL unit_test_log_t : public test_observer {
  88. public:
  89. // test_observer interface implementation
  90. virtual void test_start( counter_t test_cases_amount );
  91. virtual void test_finish();
  92. virtual void test_aborted();
  93. virtual void test_unit_start( test_unit const& );
  94. virtual void test_unit_finish( test_unit const&, unsigned long elapsed );
  95. virtual void test_unit_skipped( test_unit const&, const_string );
  96. virtual void test_unit_aborted( test_unit const& );
  97. virtual void test_unit_timed_out( test_unit const& );
  98. virtual void exception_caught( execution_exception const& ex );
  99. virtual int priority() { return 2; }
  100. // log configuration methods
  101. //! Sets the stream for all loggers
  102. //!
  103. //! This will override the log sink/stream of all loggers, whether enabled or not.
  104. void set_stream( std::ostream& );
  105. //! Sets the stream for specific logger
  106. //!
  107. //! @note Has no effect if the specified format is not found
  108. //! @par Since Boost 1.62
  109. void set_stream( output_format, std::ostream& );
  110. //! Returns a pointer to the stream associated to specific logger
  111. //!
  112. //! @note Returns a null pointer if the format is not found
  113. //! @par Since Boost 1.67
  114. std::ostream* get_stream( output_format ) const;
  115. //! Sets the threshold level for all loggers/formatters.
  116. //!
  117. //! This will override the log level of all loggers, whether enabled or not.
  118. void set_threshold_level( log_level );
  119. //! Sets the threshold/log level of a specific format
  120. //!
  121. //! @note Has no effect if the specified format is not found
  122. //! @par Since Boost 1.62
  123. void set_threshold_level( output_format, log_level );
  124. //! Add a format to the set of loggers
  125. //!
  126. //! Adding a logger means that the specified logger is enabled. The log level is managed by the formatter itself
  127. //! and specifies what events are forwarded to the underlying formatter.
  128. //! @par Since Boost 1.62
  129. void add_format( output_format );
  130. //! Sets the format of the logger
  131. //!
  132. //! This will become the only active format of the logs.
  133. void set_format( output_format );
  134. //! Returns the logger instance for a specific format.
  135. //!
  136. //! @returns the logger/formatter instance, or @c (unit_test_log_formatter*)0 if the format is not found.
  137. //! @par Since Boost 1.62
  138. unit_test_log_formatter* get_formatter( output_format );
  139. //! Sets the logger instance
  140. //!
  141. //! The specified logger becomes the unique active one. The custom log formatter has the
  142. //! format @c OF_CUSTOM_LOGGER. If such a format exists already, its formatter gets replaced by the one
  143. //! given in argument.
  144. //!
  145. //! The log level and output stream of the new formatter are taken from the currently active logger. In case
  146. //! several loggers are active, the order of priority is CUSTOM, HRF, XML, and JUNIT.
  147. //! If (unit_test_log_formatter*)0 is given as argument, the custom logger (if any) is removed.
  148. //!
  149. //! @note The ownership of the pointer is transfered to the Boost.Test framework. This call is equivalent to
  150. //! - a call to @c add_formatter
  151. //! - a call to @c set_format(OF_CUSTOM_LOGGER)
  152. //! - a configuration of the newly added logger with a previously configured stream and log level.
  153. void set_formatter( unit_test_log_formatter* );
  154. //! Adds a custom log formatter to the set of formatters
  155. //!
  156. //! The specified logger is added with the format @c OF_CUSTOM_LOGGER, such that it can
  157. //! be futher selected or its stream/log level can be specified.
  158. //! If there is already a custom logger (with @c OF_CUSTOM_LOGGER), then
  159. //! the existing one gets replaced by the one given in argument.
  160. //! The provided logger is added with an enabled state.
  161. //! If (unit_test_log_formatter*)0 is given as argument, the custom logger (if any) is removed and
  162. //! no other action is performed.
  163. //!
  164. //! @note The ownership of the pointer is transfered to the Boost.Test framework.
  165. //! @par Since Boost 1.62
  166. void add_formatter( unit_test_log_formatter* the_formatter );
  167. // test progress logging
  168. void set_checkpoint( const_string file, std::size_t line_num, const_string msg = const_string() );
  169. // entry logging
  170. unit_test_log_t& operator<<( log::begin const& ); // begin entry
  171. unit_test_log_t& operator<<( log::end const& ); // end entry
  172. unit_test_log_t& operator<<( log_level ); // set entry level
  173. unit_test_log_t& operator<<( const_string ); // log entry value
  174. unit_test_log_t& operator<<( lazy_ostream const& ); // log entry value
  175. ut_detail::entry_value_collector operator()( log_level ); // initiate entry collection
  176. private:
  177. // Implementation helpers
  178. bool log_entry_start(output_format log_format);
  179. void log_entry_context( log_level l );
  180. void clear_entry_context();
  181. // Singleton
  182. BOOST_TEST_SINGLETON_CONS( unit_test_log_t )
  183. }; // unit_test_log_t
  184. BOOST_TEST_SINGLETON_INST( unit_test_log )
  185. // helper macros
  186. #define BOOST_TEST_LOG_ENTRY( ll ) \
  187. (::boost::unit_test::unit_test_log \
  188. << ::boost::unit_test::log::begin( BOOST_TEST_L(__FILE__), __LINE__ ))(ll) \
  189. /**/
  190. } // namespace unit_test
  191. } // namespace boost
  192. // ************************************************************************** //
  193. // ************** Unit test log interface helpers ************** //
  194. // ************************************************************************** //
  195. // messages sent by the framework
  196. #define BOOST_TEST_FRAMEWORK_MESSAGE( M ) \
  197. (::boost::unit_test::unit_test_log \
  198. << ::boost::unit_test::log::begin( \
  199. "boost.test framework", \
  200. 0 )) \
  201. ( ::boost::unit_test::log_messages ) \
  202. << BOOST_TEST_LAZY_MSG( M ) \
  203. /**/
  204. #define BOOST_TEST_MESSAGE( M ) \
  205. BOOST_TEST_LOG_ENTRY( ::boost::unit_test::log_messages ) \
  206. << BOOST_TEST_LAZY_MSG( M ) \
  207. /**/
  208. //____________________________________________________________________________//
  209. #define BOOST_TEST_PASSPOINT() \
  210. ::boost::unit_test::unit_test_log.set_checkpoint( \
  211. BOOST_TEST_L(__FILE__), \
  212. static_cast<std::size_t>(__LINE__) ) \
  213. /**/
  214. //____________________________________________________________________________//
  215. #define BOOST_TEST_CHECKPOINT( M ) \
  216. ::boost::unit_test::unit_test_log.set_checkpoint( \
  217. BOOST_TEST_L(__FILE__), \
  218. static_cast<std::size_t>(__LINE__), \
  219. (::boost::wrap_stringstream().ref() << M).str() ) \
  220. /**/
  221. //____________________________________________________________________________//
  222. #include <boost/test/detail/enable_warnings.hpp>
  223. #endif // BOOST_TEST_UNIT_TEST_LOG_HPP_071894GER