1 | // (C) Copyright 2016 Raffi Enficiaud. |
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 |
9 | ///@brief Contains the definition of the Junit log formatter (OF_JUNIT) |
10 | // *************************************************************************** |
11 | |
12 | #ifndef BOOST_TEST_JUNIT_LOG_FORMATTER__ |
13 | #define BOOST_TEST_JUNIT_LOG_FORMATTER__ |
14 | |
15 | // Boost.Test |
16 | #include <boost/test/detail/global_typedef.hpp> |
17 | #include <boost/test/unit_test_log_formatter.hpp> |
18 | #include <boost/test/tree/test_unit.hpp> |
19 | |
20 | //#include <boost/test/results_collector.hpp> |
21 | |
22 | // STL |
23 | #include <cstddef> // std::size_t |
24 | #include <map> |
25 | #include <list> |
26 | |
27 | #include <boost/test/detail/suppress_warnings.hpp> |
28 | |
29 | //____________________________________________________________________________// |
30 | |
31 | namespace boost { |
32 | namespace unit_test { |
33 | namespace output { |
34 | |
35 | |
36 | namespace junit_impl { |
37 | |
38 | // helper for the JUnit logger |
39 | struct junit_log_helper |
40 | { |
41 | struct assertion_entry { |
42 | |
43 | enum log_entry_t { |
44 | log_entry_info, |
45 | log_entry_error, |
46 | log_entry_failure |
47 | }; |
48 | |
49 | assertion_entry() : sealed(false) |
50 | {} |
51 | |
52 | std::string logentry_message; // the message associated to the JUnit error/entry |
53 | std::string logentry_type; // the one that will get expanded in the final junit (failure, error) |
54 | std::string output; // additional information/message generated by the assertion |
55 | |
56 | log_entry_t log_entry; // the type associated to the assertion (or error) |
57 | |
58 | bool sealed; // indicates if the entry can accept additional information |
59 | }; |
60 | |
61 | std::list<std::string> system_out; // sysout: additional information |
62 | std::list<std::string> system_err; // syserr: additional information |
63 | std::string skipping_reason; |
64 | |
65 | // list of failure, errors and messages (assertions message and the full log) |
66 | std::vector< assertion_entry > assertion_entries; |
67 | |
68 | bool skipping; |
69 | |
70 | junit_log_helper(): skipping(false) |
71 | {} |
72 | |
73 | void clear() { |
74 | assertion_entries.clear(); |
75 | system_out.clear(); |
76 | system_err.clear(); |
77 | skipping_reason.clear(); |
78 | skipping = false; |
79 | } |
80 | |
81 | }; |
82 | } |
83 | |
84 | // ************************************************************************** // |
85 | // ************** junit_log_formatter ************** // |
86 | // ************************************************************************** // |
87 | |
88 | /// JUnit logger class |
89 | class junit_log_formatter : public unit_test_log_formatter { |
90 | public: |
91 | |
92 | junit_log_formatter() : m_display_build_info(false) |
93 | { |
94 | // we log everything from the logger singleton point of view |
95 | // because we need to know about all the messages/commands going to the logger |
96 | // we decide what we put inside the logs internally |
97 | this->m_log_level = log_successful_tests; |
98 | m_log_level_internal = log_messages; |
99 | } |
100 | |
101 | // Formatter interface |
102 | void log_start( std::ostream&, counter_t test_cases_amount ) BOOST_OVERRIDE; |
103 | void log_finish( std::ostream& ) BOOST_OVERRIDE; |
104 | void log_build_info( std::ostream&, bool ) BOOST_OVERRIDE; |
105 | |
106 | void test_unit_start( std::ostream&, test_unit const& tu ) BOOST_OVERRIDE; |
107 | void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed ) BOOST_OVERRIDE; |
108 | void test_unit_skipped( std::ostream&, test_unit const& tu, const_string reason ) BOOST_OVERRIDE; |
109 | void test_unit_aborted( std::ostream& os, test_unit const& tu ) BOOST_OVERRIDE; |
110 | void test_unit_timed_out( std::ostream& os, test_unit const& tu) BOOST_OVERRIDE; |
111 | |
112 | void log_exception_start( std::ostream&, log_checkpoint_data const&, execution_exception const& ex ) BOOST_OVERRIDE; |
113 | void log_exception_finish( std::ostream& ) BOOST_OVERRIDE; |
114 | |
115 | void log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let ) BOOST_OVERRIDE; |
116 | |
117 | using unit_test_log_formatter::log_entry_value; // bring base class functions into overload set |
118 | void log_entry_value( std::ostream&, const_string value ) BOOST_OVERRIDE; |
119 | void log_entry_finish( std::ostream& ) BOOST_OVERRIDE; |
120 | |
121 | void entry_context_start( std::ostream&, log_level ) BOOST_OVERRIDE; |
122 | void log_entry_context( std::ostream&, log_level, const_string ) BOOST_OVERRIDE; |
123 | void entry_context_finish( std::ostream&, log_level ) BOOST_OVERRIDE; |
124 | |
125 | //! Discards changes in the log level |
126 | void set_log_level(log_level ll) BOOST_OVERRIDE |
127 | { |
128 | if(ll > log_successful_tests && ll < log_messages) |
129 | ll = log_successful_tests; |
130 | else if (ll > log_all_errors) |
131 | ll = log_all_errors; |
132 | |
133 | this->m_log_level_internal = ll; |
134 | } |
135 | |
136 | //! Instead of a regular stream, returns a file name corresponding to |
137 | //! the current master test suite. If the file already exists, adds an index |
138 | //! to it. |
139 | std::string get_default_stream_description() const BOOST_OVERRIDE; |
140 | |
141 | |
142 | private: |
143 | typedef std::map<test_unit_id, junit_impl::junit_log_helper> map_trace_t; |
144 | map_trace_t map_tests; |
145 | junit_impl::junit_log_helper runner_log_entry; |
146 | |
147 | junit_impl::junit_log_helper& get_current_log_entry() { |
148 | if(list_path_to_root.empty()) |
149 | return runner_log_entry; |
150 | map_trace_t::iterator it = map_tests.find(x: list_path_to_root.back()); |
151 | return (it == map_tests.end() ? runner_log_entry : it->second); |
152 | } |
153 | |
154 | std::list<test_unit_id> list_path_to_root; |
155 | bool m_display_build_info; |
156 | bool m_is_last_assertion_or_error; // true if failure, false if error |
157 | |
158 | log_level m_log_level_internal; |
159 | friend class junit_result_helper; |
160 | }; |
161 | |
162 | } // namespace output |
163 | } // namespace unit_test |
164 | } // namespace boost |
165 | |
166 | #include <boost/test/detail/enable_warnings.hpp> |
167 | |
168 | #endif // BOOST_TEST_JUNIT_LOG_FORMATTER__ |
169 | |