unit_test_log.ipp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  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 : $RCSfile$
  8. //
  9. // Version : $Revision$
  10. //
  11. // Description : implemets Unit Test Log
  12. // ***************************************************************************
  13. #ifndef BOOST_TEST_UNIT_TEST_LOG_IPP_012205GER
  14. #define BOOST_TEST_UNIT_TEST_LOG_IPP_012205GER
  15. // Boost.Test
  16. #include <boost/test/unit_test_log.hpp>
  17. #include <boost/test/unit_test_log_formatter.hpp>
  18. #include <boost/test/execution_monitor.hpp>
  19. #include <boost/test/framework.hpp>
  20. #include <boost/test/unit_test_parameters.hpp>
  21. #include <boost/test/utils/basic_cstring/compare.hpp>
  22. #include <boost/test/utils/foreach.hpp>
  23. #include <boost/test/output/compiler_log_formatter.hpp>
  24. #include <boost/test/output/xml_log_formatter.hpp>
  25. #include <boost/test/output/junit_log_formatter.hpp>
  26. // Boost
  27. #include <boost/shared_ptr.hpp>
  28. #include <boost/io/ios_state.hpp>
  29. typedef ::boost::io::ios_base_all_saver io_saver_type;
  30. #include <boost/test/detail/suppress_warnings.hpp>
  31. //____________________________________________________________________________//
  32. namespace boost {
  33. namespace unit_test {
  34. // ************************************************************************** //
  35. // ************** entry_value_collector ************** //
  36. // ************************************************************************** //
  37. namespace ut_detail {
  38. entry_value_collector const&
  39. entry_value_collector::operator<<( lazy_ostream const& v ) const
  40. {
  41. unit_test_log << v;
  42. return *this;
  43. }
  44. //____________________________________________________________________________//
  45. entry_value_collector const&
  46. entry_value_collector::operator<<( const_string v ) const
  47. {
  48. unit_test_log << v;
  49. return *this;
  50. }
  51. //____________________________________________________________________________//
  52. entry_value_collector::~entry_value_collector()
  53. {
  54. if( m_last )
  55. unit_test_log << log::end();
  56. }
  57. //____________________________________________________________________________//
  58. } // namespace ut_detail
  59. // ************************************************************************** //
  60. // ************** unit_test_log ************** //
  61. // ************************************************************************** //
  62. namespace {
  63. // log data
  64. struct unit_test_log_data_helper_impl {
  65. typedef boost::shared_ptr<unit_test_log_formatter> formatter_ptr;
  66. typedef boost::shared_ptr<io_saver_type> saver_ptr;
  67. bool m_enabled;
  68. output_format m_format;
  69. std::ostream* m_stream;
  70. saver_ptr m_stream_state_saver;
  71. formatter_ptr m_log_formatter;
  72. bool m_entry_in_progress;
  73. unit_test_log_data_helper_impl(unit_test_log_formatter* p_log_formatter, output_format format, bool enabled = false)
  74. : m_enabled( enabled )
  75. , m_format( format )
  76. , m_stream( &std::cout )
  77. , m_stream_state_saver( new io_saver_type( std::cout ) )
  78. , m_log_formatter()
  79. , m_entry_in_progress( false )
  80. {
  81. m_log_formatter.reset(p_log_formatter);
  82. m_log_formatter->set_log_level(log_all_errors);
  83. }
  84. // helper functions
  85. std::ostream& stream()
  86. {
  87. return *m_stream;
  88. }
  89. log_level get_log_level() const
  90. {
  91. return m_log_formatter->get_log_level();
  92. }
  93. };
  94. struct unit_test_log_impl {
  95. // Constructor
  96. unit_test_log_impl()
  97. {
  98. m_log_formatter_data.push_back( unit_test_log_data_helper_impl(new output::compiler_log_formatter, OF_CLF, true) ); // only this one is active by default,
  99. m_log_formatter_data.push_back( unit_test_log_data_helper_impl(new output::xml_log_formatter, OF_XML, false) );
  100. m_log_formatter_data.push_back( unit_test_log_data_helper_impl(new output::junit_log_formatter, OF_JUNIT, false) );
  101. }
  102. typedef std::vector<unit_test_log_data_helper_impl> v_formatter_data_t;
  103. v_formatter_data_t m_log_formatter_data;
  104. typedef std::vector<unit_test_log_data_helper_impl*> vp_formatter_data_t;
  105. vp_formatter_data_t m_active_log_formatter_data;
  106. // entry data
  107. log_entry_data m_entry_data;
  108. bool has_entry_in_progress() const {
  109. for( vp_formatter_data_t::const_iterator it(m_active_log_formatter_data.begin()), ite(m_active_log_formatter_data.end());
  110. it < ite;
  111. ++it)
  112. {
  113. unit_test_log_data_helper_impl& current_logger_data = **it;
  114. if( current_logger_data.m_entry_in_progress )
  115. return true;
  116. }
  117. return false;
  118. }
  119. // check point data
  120. log_checkpoint_data m_checkpoint_data;
  121. void set_checkpoint( const_string file, std::size_t line_num, const_string msg )
  122. {
  123. assign_op( m_checkpoint_data.m_message, msg, 0 );
  124. m_checkpoint_data.m_file_name = file;
  125. m_checkpoint_data.m_line_num = line_num;
  126. }
  127. };
  128. unit_test_log_impl& s_log_impl() { static unit_test_log_impl the_inst; return the_inst; }
  129. //____________________________________________________________________________//
  130. void
  131. log_entry_context( log_level l, unit_test_log_data_helper_impl& current_logger_data)
  132. {
  133. framework::context_generator const& context = framework::get_context();
  134. if( context.is_empty() )
  135. return;
  136. const_string frame;
  137. current_logger_data.m_log_formatter->entry_context_start( current_logger_data.stream(), l );
  138. while( !(frame=context.next()).is_empty() )
  139. {
  140. current_logger_data.m_log_formatter->log_entry_context( current_logger_data.stream(), l, frame );
  141. }
  142. current_logger_data.m_log_formatter->entry_context_finish( current_logger_data.stream(), l );
  143. }
  144. //____________________________________________________________________________//
  145. void
  146. clear_entry_context()
  147. {
  148. framework::clear_context();
  149. }
  150. // convenience
  151. typedef unit_test_log_impl::vp_formatter_data_t vp_logger_t;
  152. typedef unit_test_log_impl::v_formatter_data_t v_logger_t;
  153. } // local namespace
  154. //____________________________________________________________________________//
  155. BOOST_TEST_SINGLETON_CONS_IMPL( unit_test_log_t )
  156. void
  157. unit_test_log_t::configure( )
  158. {
  159. // configure is not test_start:
  160. // test_start pushes the necessary log information when the test module is starting, and implies configure.
  161. // configure: should be called each time the set of loggers, stream or configuration is changed.
  162. s_log_impl().m_active_log_formatter_data.clear();
  163. for( unit_test_log_impl::v_formatter_data_t::iterator it(s_log_impl().m_log_formatter_data.begin()),
  164. ite(s_log_impl().m_log_formatter_data.end());
  165. it < ite;
  166. ++it)
  167. {
  168. if( !it->m_enabled || it->get_log_level() == log_nothing )
  169. continue;
  170. s_log_impl().m_active_log_formatter_data.push_back(&*it);
  171. it->m_entry_in_progress = false;
  172. }
  173. }
  174. //____________________________________________________________________________//
  175. void
  176. unit_test_log_t::test_start( counter_t test_cases_amount, test_unit_id )
  177. {
  178. configure();
  179. vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
  180. for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  181. {
  182. unit_test_log_data_helper_impl& current_logger_data = **it;
  183. current_logger_data.m_log_formatter->log_start( current_logger_data.stream(), test_cases_amount );
  184. current_logger_data.m_log_formatter->log_build_info(
  185. current_logger_data.stream(),
  186. runtime_config::get<bool>( runtime_config::btrt_build_info ));
  187. //current_logger_data.stream().flush();
  188. }
  189. }
  190. //____________________________________________________________________________//
  191. void
  192. unit_test_log_t::test_finish()
  193. {
  194. vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
  195. for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  196. {
  197. unit_test_log_data_helper_impl& current_logger_data = **it;
  198. current_logger_data.m_log_formatter->log_finish( current_logger_data.stream() );
  199. current_logger_data.stream().flush();
  200. }
  201. }
  202. //____________________________________________________________________________//
  203. void
  204. unit_test_log_t::test_aborted()
  205. {
  206. BOOST_TEST_LOG_ENTRY( log_messages ) << "Test is aborted";
  207. }
  208. //____________________________________________________________________________//
  209. void
  210. unit_test_log_t::test_unit_start( test_unit const& tu )
  211. {
  212. if( s_log_impl().has_entry_in_progress() )
  213. *this << log::end();
  214. vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
  215. for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  216. {
  217. unit_test_log_data_helper_impl& current_logger_data = **it;
  218. if( current_logger_data.get_log_level() > log_test_units )
  219. continue;
  220. current_logger_data.m_log_formatter->test_unit_start( current_logger_data.stream(), tu );
  221. }
  222. }
  223. //____________________________________________________________________________//
  224. void
  225. unit_test_log_t::test_unit_finish( test_unit const& tu, unsigned long elapsed )
  226. {
  227. s_log_impl().m_checkpoint_data.clear();
  228. if( s_log_impl().has_entry_in_progress() )
  229. *this << log::end();
  230. vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
  231. for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  232. {
  233. unit_test_log_data_helper_impl& current_logger_data = **it;
  234. if( current_logger_data.get_log_level() > log_test_units )
  235. continue;
  236. current_logger_data.m_log_formatter->test_unit_finish( current_logger_data.stream(), tu, elapsed );
  237. }
  238. }
  239. //____________________________________________________________________________//
  240. void
  241. unit_test_log_t::test_unit_skipped( test_unit const& tu, const_string reason )
  242. {
  243. if( s_log_impl().has_entry_in_progress() )
  244. *this << log::end();
  245. vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
  246. for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  247. {
  248. unit_test_log_data_helper_impl& current_logger_data = **it;
  249. if( current_logger_data.get_log_level() > log_test_units )
  250. continue;
  251. current_logger_data.m_log_formatter->test_unit_skipped( current_logger_data.stream(), tu, reason );
  252. }
  253. }
  254. void
  255. unit_test_log_t::test_unit_aborted( test_unit const& tu )
  256. {
  257. if( s_log_impl().has_entry_in_progress() )
  258. *this << log::end();
  259. vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
  260. for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  261. {
  262. unit_test_log_data_helper_impl& current_logger_data = **it;
  263. if( current_logger_data.get_log_level() > log_test_units )
  264. continue;
  265. current_logger_data.m_log_formatter->test_unit_aborted(current_logger_data.stream(), tu );
  266. }
  267. }
  268. void
  269. unit_test_log_t::test_unit_timed_out( test_unit const& tu )
  270. {
  271. if( s_log_impl().has_entry_in_progress() )
  272. *this << log::end();
  273. vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
  274. for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  275. {
  276. unit_test_log_data_helper_impl& current_logger_data = **it;
  277. if( current_logger_data.get_log_level() > log_test_units )
  278. continue;
  279. current_logger_data.m_log_formatter->test_unit_timed_out(current_logger_data.stream(), tu );
  280. }
  281. }
  282. //____________________________________________________________________________//
  283. void
  284. unit_test_log_t::exception_caught( execution_exception const& ex )
  285. {
  286. log_level l =
  287. ex.code() <= execution_exception::cpp_exception_error ? log_cpp_exception_errors :
  288. (ex.code() <= execution_exception::timeout_error ? log_system_errors
  289. : log_fatal_errors );
  290. if( s_log_impl().has_entry_in_progress() )
  291. *this << log::end();
  292. vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
  293. for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  294. {
  295. unit_test_log_data_helper_impl& current_logger_data = **it;
  296. if( l >= current_logger_data.get_log_level() ) {
  297. current_logger_data.m_log_formatter->log_exception_start( current_logger_data.stream(), s_log_impl().m_checkpoint_data, ex );
  298. log_entry_context( l, current_logger_data );
  299. current_logger_data.m_log_formatter->log_exception_finish( current_logger_data.stream() );
  300. }
  301. }
  302. clear_entry_context();
  303. }
  304. //____________________________________________________________________________//
  305. void
  306. unit_test_log_t::set_checkpoint( const_string file, std::size_t line_num, const_string msg )
  307. {
  308. s_log_impl().set_checkpoint( file, line_num, msg );
  309. }
  310. //____________________________________________________________________________//
  311. char
  312. set_unix_slash( char in )
  313. {
  314. return in == '\\' ? '/' : in;
  315. }
  316. unit_test_log_t&
  317. unit_test_log_t::operator<<( log::begin const& b )
  318. {
  319. if( s_log_impl().has_entry_in_progress() )
  320. *this << log::end();
  321. vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
  322. for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  323. {
  324. unit_test_log_data_helper_impl& current_logger_data = **it;
  325. current_logger_data.m_stream_state_saver->restore();
  326. }
  327. s_log_impl().m_entry_data.clear();
  328. assign_op( s_log_impl().m_entry_data.m_file_name, b.m_file_name, 0 );
  329. // normalize file name
  330. std::transform( s_log_impl().m_entry_data.m_file_name.begin(), s_log_impl().m_entry_data.m_file_name.end(),
  331. s_log_impl().m_entry_data.m_file_name.begin(),
  332. &set_unix_slash );
  333. s_log_impl().m_entry_data.m_line_num = b.m_line_num;
  334. return *this;
  335. }
  336. //____________________________________________________________________________//
  337. unit_test_log_t&
  338. unit_test_log_t::operator<<( log::end const& )
  339. {
  340. if( s_log_impl().has_entry_in_progress() ) {
  341. vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
  342. log_level l = s_log_impl().m_entry_data.m_level;
  343. for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  344. {
  345. unit_test_log_data_helper_impl& current_logger_data = **it;
  346. if( current_logger_data.m_entry_in_progress ) {
  347. if( l >= current_logger_data.get_log_level() ) {
  348. log_entry_context( l, current_logger_data );
  349. }
  350. current_logger_data.m_log_formatter->log_entry_finish( current_logger_data.stream() );
  351. }
  352. current_logger_data.m_entry_in_progress = false;
  353. }
  354. }
  355. clear_entry_context();
  356. return *this;
  357. }
  358. //____________________________________________________________________________//
  359. unit_test_log_t&
  360. unit_test_log_t::operator<<( log_level l )
  361. {
  362. s_log_impl().m_entry_data.m_level = l;
  363. return *this;
  364. }
  365. //____________________________________________________________________________//
  366. ut_detail::entry_value_collector
  367. unit_test_log_t::operator()( log_level l )
  368. {
  369. *this << l;
  370. return ut_detail::entry_value_collector();
  371. }
  372. //____________________________________________________________________________//
  373. bool
  374. log_entry_start(unit_test_log_data_helper_impl &current_logger_data)
  375. {
  376. if( current_logger_data.m_entry_in_progress )
  377. return true;
  378. switch( s_log_impl().m_entry_data.m_level ) {
  379. case log_successful_tests:
  380. current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
  381. unit_test_log_formatter::BOOST_UTL_ET_INFO );
  382. break;
  383. case log_messages:
  384. current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
  385. unit_test_log_formatter::BOOST_UTL_ET_MESSAGE );
  386. break;
  387. case log_warnings:
  388. current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
  389. unit_test_log_formatter::BOOST_UTL_ET_WARNING );
  390. break;
  391. case log_all_errors:
  392. case log_cpp_exception_errors:
  393. case log_system_errors:
  394. current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
  395. unit_test_log_formatter::BOOST_UTL_ET_ERROR );
  396. break;
  397. case log_fatal_errors:
  398. current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
  399. unit_test_log_formatter::BOOST_UTL_ET_FATAL_ERROR );
  400. break;
  401. case log_nothing:
  402. case log_test_units:
  403. case invalid_log_level:
  404. return false;
  405. }
  406. current_logger_data.m_entry_in_progress = true;
  407. return true;
  408. }
  409. //____________________________________________________________________________//
  410. unit_test_log_t&
  411. unit_test_log_t::operator<<( const_string value )
  412. {
  413. if(value.empty()) {
  414. return *this;
  415. }
  416. vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
  417. for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  418. {
  419. unit_test_log_data_helper_impl& current_logger_data = **it;
  420. if( s_log_impl().m_entry_data.m_level >= current_logger_data.get_log_level() )
  421. if( log_entry_start(current_logger_data) ) {
  422. current_logger_data.m_log_formatter->log_entry_value( current_logger_data.stream(), value );
  423. }
  424. }
  425. return *this;
  426. }
  427. //____________________________________________________________________________//
  428. unit_test_log_t&
  429. unit_test_log_t::operator<<( lazy_ostream const& value )
  430. {
  431. if(value.empty()) {
  432. return *this;
  433. }
  434. vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
  435. for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  436. {
  437. unit_test_log_data_helper_impl& current_logger_data = **it;
  438. if( s_log_impl().m_entry_data.m_level >= current_logger_data.get_log_level() ) {
  439. if( log_entry_start(current_logger_data) ) {
  440. current_logger_data.m_log_formatter->log_entry_value( current_logger_data.stream(), value );
  441. }
  442. }
  443. }
  444. return *this;
  445. }
  446. //____________________________________________________________________________//
  447. void
  448. unit_test_log_t::set_stream( std::ostream& str )
  449. {
  450. if( s_log_impl().has_entry_in_progress() )
  451. return;
  452. v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
  453. for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  454. {
  455. unit_test_log_data_helper_impl& current_logger_data = *it;
  456. current_logger_data.m_stream = &str;
  457. current_logger_data.m_stream_state_saver.reset( new io_saver_type( str ) );
  458. }
  459. }
  460. //____________________________________________________________________________//
  461. void
  462. unit_test_log_t::set_stream( output_format log_format, std::ostream& str )
  463. {
  464. if( s_log_impl().has_entry_in_progress() )
  465. return;
  466. v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
  467. for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  468. {
  469. unit_test_log_data_helper_impl& current_logger_data = *it;
  470. if( current_logger_data.m_format == log_format) {
  471. current_logger_data.m_stream = &str;
  472. current_logger_data.m_stream_state_saver.reset( new io_saver_type( str ) );
  473. break;
  474. }
  475. }
  476. }
  477. std::ostream*
  478. unit_test_log_t::get_stream( output_format log_format ) const
  479. {
  480. v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
  481. for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  482. {
  483. unit_test_log_data_helper_impl& current_logger_data = *it;
  484. if( current_logger_data.m_format == log_format) {
  485. return current_logger_data.m_stream;
  486. }
  487. }
  488. return 0;
  489. }
  490. //____________________________________________________________________________//
  491. log_level
  492. unit_test_log_t::set_threshold_level( log_level lev )
  493. {
  494. if( s_log_impl().has_entry_in_progress() || lev == invalid_log_level )
  495. return invalid_log_level;
  496. log_level ret = log_nothing;
  497. v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
  498. for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  499. {
  500. unit_test_log_data_helper_impl& current_logger_data = *it;
  501. ret = (std::min)(ret, current_logger_data.m_log_formatter->get_log_level());
  502. current_logger_data.m_log_formatter->set_log_level( lev );
  503. }
  504. return ret;
  505. }
  506. //____________________________________________________________________________//
  507. log_level
  508. unit_test_log_t::set_threshold_level( output_format log_format, log_level lev )
  509. {
  510. if( s_log_impl().has_entry_in_progress() || lev == invalid_log_level )
  511. return invalid_log_level;
  512. log_level ret = log_nothing;
  513. v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
  514. for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  515. {
  516. unit_test_log_data_helper_impl& current_logger_data = *it;
  517. if( current_logger_data.m_format == log_format) {
  518. ret = current_logger_data.m_log_formatter->get_log_level();
  519. current_logger_data.m_log_formatter->set_log_level( lev );
  520. break;
  521. }
  522. }
  523. return ret;
  524. }
  525. //____________________________________________________________________________//
  526. void
  527. unit_test_log_t::set_format( output_format log_format )
  528. {
  529. if( s_log_impl().has_entry_in_progress() )
  530. return;
  531. v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
  532. for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  533. {
  534. unit_test_log_data_helper_impl& current_logger_data = *it;
  535. current_logger_data.m_enabled = current_logger_data.m_format == log_format;
  536. }
  537. }
  538. //____________________________________________________________________________//
  539. void
  540. unit_test_log_t::add_format( output_format log_format )
  541. {
  542. if( s_log_impl().has_entry_in_progress() )
  543. return;
  544. v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
  545. for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  546. {
  547. unit_test_log_data_helper_impl& current_logger_data = *it;
  548. if( current_logger_data.m_format == log_format) {
  549. current_logger_data.m_enabled = true;
  550. break;
  551. }
  552. }
  553. }
  554. //____________________________________________________________________________//
  555. unit_test_log_formatter*
  556. unit_test_log_t::get_formatter( output_format log_format ) {
  557. v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
  558. for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  559. {
  560. unit_test_log_data_helper_impl& current_logger_data = *it;
  561. if( current_logger_data.m_format == log_format) {
  562. return current_logger_data.m_log_formatter.get();
  563. }
  564. }
  565. return 0;
  566. }
  567. void
  568. unit_test_log_t::add_formatter( unit_test_log_formatter* the_formatter )
  569. {
  570. // remove only user defined logger
  571. v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
  572. for(v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  573. {
  574. if( it->m_format == OF_CUSTOM_LOGGER) {
  575. s_log_impl().m_log_formatter_data.erase(it);
  576. break;
  577. }
  578. }
  579. if( the_formatter ) {
  580. s_log_impl().m_active_log_formatter_data.clear(); // otherwise dandling references
  581. vloggers.push_back( unit_test_log_data_helper_impl(the_formatter, OF_CUSTOM_LOGGER, true) );
  582. }
  583. }
  584. void
  585. unit_test_log_t::set_formatter( unit_test_log_formatter* the_formatter )
  586. {
  587. if( s_log_impl().has_entry_in_progress() )
  588. return;
  589. // remove only user defined logger
  590. log_level current_level = invalid_log_level;
  591. std::ostream *current_stream = 0;
  592. output_format previous_format = OF_INVALID;
  593. v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
  594. for(v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
  595. {
  596. if( it->m_enabled ) {
  597. if( current_level == invalid_log_level || it->m_format < previous_format || it->m_format == OF_CUSTOM_LOGGER) {
  598. current_level = it->get_log_level();
  599. current_stream = &(it->stream());
  600. previous_format = it->m_format;
  601. }
  602. }
  603. }
  604. if( the_formatter ) {
  605. add_formatter(the_formatter);
  606. set_format(OF_CUSTOM_LOGGER);
  607. set_threshold_level(OF_CUSTOM_LOGGER, current_level);
  608. set_stream(OF_CUSTOM_LOGGER, *current_stream);
  609. }
  610. configure();
  611. }
  612. //____________________________________________________________________________//
  613. // ************************************************************************** //
  614. // ************** unit_test_log_formatter ************** //
  615. // ************************************************************************** //
  616. void
  617. unit_test_log_formatter::log_entry_value( std::ostream& ostr, lazy_ostream const& value )
  618. {
  619. log_entry_value( ostr, (wrap_stringstream().ref() << value).str() );
  620. }
  621. void
  622. unit_test_log_formatter::set_log_level(log_level new_log_level)
  623. {
  624. m_log_level = new_log_level;
  625. }
  626. log_level
  627. unit_test_log_formatter::get_log_level() const
  628. {
  629. return m_log_level;
  630. }
  631. //____________________________________________________________________________//
  632. } // namespace unit_test
  633. } // namespace boost
  634. #include <boost/test/detail/enable_warnings.hpp>
  635. #endif // BOOST_TEST_UNIT_TEST_LOG_IPP_012205GER