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